Qt QMap의 iterator와 auto 상식 +1
안녕하세요.
간단하게 QMAP 클래스 사용하다가 iterator방법에 대해서 좀 더 알고 있으면 좋을 것 같아서 간략하게 남겨 보았습니다. 테스트 환경은 Qt 6.8.1입니다.
1. QMap은?
Qt 프레임워크에서 제공하는 데이터 컨테이너 클래스로, 키(key)와 값(value)의 쌍을 저장하는 연관 컨테이너입니다. 이는 정렬된 맵(sorted map) 자료 구조로 구현되며, 키가 자동으로 정렬됩니다.
QMap 사용법은 알고 있으리라 생각되어서 자세한 방법은 넘어가도록 하겠습니다.
간단하게 설명하자면 템플릿(template) 또는 제네릭(generic) 타입으로 변수를 선언하고, 키와 값을 쌍으로 저장하거나 읽으면 됩니다.
<사용 예>
QMap<QString, int> map;
map["Apple"] = 1;
map.insert("Date", 4); // insert() 메서드를 사용한 삽입
int value = map["Apple"]; // 키를 통해 값 조회
2. iterator 사용방법
QMap 데이터를 확인하는 방법으로 while문, for, foreach 등 몇 가지가 있지만, 그중에 for 문으로 간단하게 iterator에 대해서 알아보겠습니다.
3개의 데이터 쌍을 입력합니다. for문을 작성해서 key값과 value를 출력하는 코드입니다.
#include <QMap>
#include <QString>
QMap<QString, int> map;
// main 등 코드 생략
map["first"] = 1;
map["second"] = 2;
map["third"] = 3;
for(auto it = map.cbegin();it != map.cend(); ++it)
{
qDebug() << it.key() << " : " << it.value();
}
위에서 보면 iterator를 직접적으로 선언한 곳은 없습니다. 그러나 auto라는 것을 사용한 것을 알 수 있습니다.
auto를 사용하는 이유는 코드의 간결성과 가독성을 높이기 위해서입니다. C++에서 auto는 변수의 타입을 컴파일러가 자동으로 추론하도록 해주는 키워드입니다.
이를 통해, 특히 복잡한 자료형을 다룰 때 코드가 더 읽기 쉬워지고, 변경 사항에 더 유연하게 대응할 수 있습니다.
예를 들어, QMap<QString, int>::const_iterator와 같은 긴 자료형을 직접 쓰는 대신, auto를 사용하면 다음과 같이 간결하게 표현할 수 있습니다:
map의 begin(), end() 멤버 함수도 있지만, 여기서는 cbegin()과 cend()를 사용했습니다. 차이는 QMap 데이터를 읽기 전용으로 순회합니다. 이렇게 하면 데이터를 수정하지 않으면서 읽기 효율성을 높일 수 있습니다.
auto의 주요 이점과 단점
복잡한 자료형을 명시할 필요 없이, 컴파일러가 적절한 타입을 자동으로 추론해 주기 때문에 코드의 간소화가 가능합니다.
자료형을 변경하더라도 코드 수정이 최소화됩니다. 예를 들어, QMap 대신 다른 자료형으로 교체해도 auto를 쓰면 타입 변경을 신경 쓰지 않아도 됩니다.
다만, auto를 사용할 때 변수의 타입이 명확하지 않으면 가독성이 떨어질 수 있으니, 명확한 타입을 유지할 필요가 있는 경우에는 직접 자료형을 명시하는 것이 더 좋을 때도 있습니다.
참고로, 아래는 iterator 형으로 먼저 선언하고 begin() 멤버 함수를 사용한 경우입니다. 구현 내용은 동일한데 cbegin() 함수와 차이를 보여주기 위해서 값 수정하는 코드를 추가했습니다.
QMap<QString, int> map;
QMap<QString,int>::iterator it;
map["first"] = 1;
map["second"] = 2;
map["third"] = 3;
for (it = map.begin(); it != map.end(); ++it) {
if (it.key() == "third") {
it.value() = 100; // 값 수정 가능
}
qDebug() << it.key() << " : " << it.value();
}
3. while 문을 사용할 경우
추가로, while문도 알고 있으면 좋을 것 같아서 같이 좀 더 확인해 보았습니다.
while문을 사용할 경우도 읽기 전용으로 하는 경우와 변경 가능한 경우로 나눌 수 있습니다.
QMapIterator는 읽기 전용으로, 데이터 변경을 하고 싶다면 QMutableMapIterator을 사용하면 됩니다.
//QMapIterator 사용시
QMap<QString, int> map;
QMapIterator<QString, int> it{ map };
map["first"] = 1;
map["second"] = 2;
map["third"] = 3;
while ( it.hasNext() )
{
it.next();
qDebug() << "whileIterator=> "<< it.key() << " : " << it.value();
}
// QMutableMapIterator 사용시
QMutableMapIterator<QString, int> m_it{ map };
while (m_it.hasNext()) {
m_it.next();
if (m_it.key() == "Second") {
m_it.setValue(200); // 값 수정가능
}
qDebug() << "QMutableIterator=> "<< m_it.key() << " : " << m_it.value();
}
복습 차원에서 QMap에 대한 지식 +1을 해보았습니다.
감사합니다.