본문 바로가기
컴퓨터/디버깅

STL의 set 의 iterator 와 const_iterator에 따른 오류

by adnoctum 2012. 12. 6.




다음과 같은 오류가 났다. 


cluster_gene_by_robust_region.cpp:99: error: passing ‘const CRobust_Position’ as ‘this’ argument of ‘void CRobust_Position::inc_gene_count(const int&)’ discards qualifiers

환경: GCC 4.4.6 on CentOS 6.3 (Kernel Linux 2.6.32-279.14.1.el6.x86_64)


그 쉽다는 컴파일 에러인데 쉽사리 이해가 되지 않는다. 에러 내용 자체는 const CRobust_Position 을 this 로 void CRobust_Position::inc_gene_count 함수로 넘기면 qualifier 를 버리게 되기 때문에 그렇게 넘길 수 없다는 이야기 이다. qualifer 를 버리게 된다는 것은 결국 const 로 설정한 것을 그대로 유지할 수 없다는 의미일텐데, 문제는 저 함수를 호출하는 것은 결코 const 로 되어 있지 않다. 즉, 


 92 bool merge_robust_position(const std::set<CRobust_Position>& op1, std::set<CRobust_Position>* op2)

 93 {

 94 

 95         std::map<std::pair<int,int>,int> pos2gene1;

 96         std::map<std::pair<int,int>,int> pos2call1;

 97         robust_position_to_map(op1, &pos2gene1, &pos2call1);

 98 

 99         std::set<CRobust_Position>::iterator aa = op2->begin();

100         (*aa).inc_gene_count(1);


위에서 (디버깅하느로 잡코드가 있다) 보면 op2 는 pointer 로 받았고, 99 번 줄에서 iterator 로 [op2]의 원소들을 순회하고 있다. 따라서 100 번은 const 가 암묵적으로 들어 간 부분이 없다. inc_gene_count 함수는



52         void inc_gene_count(const int& inc) { /*_gene_count += inc;*/}


위처럼 되어 있다. 92, 99, 100 번 줄 어디에서도 inc_gene_count 함수가 const 일 것을 함축하는 부분이 없다. 보통 vector 같은 container 에는 const_iterator 가 iterator 와 따로 제공이 되고, const_iterator 를 사용할 경우 iterator 를 이용한 원소의 값 변경이 안되는 것에 반해 iterator 를 const_ 없이 사용할 경우 (위 99 번 줄 처럼) iterator 를 통한 값의 변경이 가능하다. 지금 위도 정확히 같은 경우인데 이 경우에는 값이 변경이 되지 않고 있다. discards qualifier 라는 에러 메세지에서 추측할 수 있는 것은 inc_gene_count 함수가 const member function 이어야 한다는 것이다. 실제로 그렇게 해서 compile 하면 에러는 없다. 


   그렇다면 왜 set 의 경우 iterator 를 통한 값의 변경이 안되는 것일까? 이것은 아마도 이럴 것이다. set 은 원소들의 검색을 빠르게 하기 위해 원소를 보통 정렬해서 저장하게 된다. 그런데 iterator 를 통해 원소의 어떤 값을 변경하게 되면 원소의 순서가 바뀌어야만 할 수도 있다. 그런데 성능을 최우선을 했던 STL 이 그렇게 비효율적으로 되어 있지는 않을 것이다. 즉, iterator 를 통한 원소의 값 변경 시 매번 원소를 재정렬해야 한다면 매우 비효율적일테고, 따라서 set 의 경우 비록 이름은 const_iterator 가 아닌 iterator 일지라도 이것을 통한 원소의 값 변경은 불가능한 것이다.