2011-04-30 2 views
5

다음 스 니펫을 고려하십시오.str :: map :: find() const 오버로드

#include <map> 

class C { 
public: 
    C() {} 

    const int& f(const int& x) const 
    { 
     // Error: cannot cast const int* to int* const 
     return myMap.find(&x)->second; 

     // With a const_cast works: 
     //return myMap.find(const_cast<int* const>(&x))->second; 
    } 

    std::map<int*, int> myMap; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int x = 0; 

    C c; 
    c.f(x); 

    return 0; 
} 

f()의 오류는 const KeyType&를 취하는 맵의 find()의 const 과부하로 인해 발생합니다. 지도의 주요 유형이 int*이므로 int* const로 바뀝니다. f()는 매개 변수가 수정되지 않으므로 const int& 매개 변수를 사용합니다.

불행하게도 이것은 const int*int* const로 형 변환하려고 시도하는데 결국 int* const은 int에 대한 const 한정자를 잃어 버리고 컴파일되지 않습니다.

매개 변수가 확실히 수정되지 않았기 때문에 일종의 짜증나는 일입니다. find()와 같이 사용되었지만 const_cast가 필요합니다.

const_cast없이 f()을 쓸 수있는 방법이 있습니까?

+1

이것은 다소 드문 경우입니다. 왜 포인터를 맵 키로 사용하고 있습니까? –

+0

내 응용 프로그램에서는 키가 중량 객체에 대한 참조가되어야하며 참조를 맵 키로 사용할 수 없습니다. – AshleysBrain

답변

5

실제 질문은 :지도의 색인이 const가 아닌 이유는 무엇입니까? const? (물론 그것이 포인터 여야한다고 가정하십시오.) 과 같은 것을 통해 인덱스를 수정할 수 있기를 정말로 원하십니까 *myMap.find(&x)->first = xxx; 당신이 이미 객체에 대한 포인터를 가지고 있다고 가정 할 때, 이는 매우 비정상적으로 이라고 말할 수 있습니다.

+0

아, 그 생각하지 않았다 - 감사합니다! – AshleysBrain

7

map의 유형을 std::map<const int*, int>으로 변경할 수 있습니다. 나는 당신이 포인터로 열쇠를 먼저 필요로하는지 의문이다. James가 지적했듯이 map을 통해 수정 대상을 절대 의도하지 않으므로 키 유형은 const int*이어야합니다. 네가 그렇게했다면 나는 더 걱정할 것이다.