C ++ 맵 액세스 액세스 퇴직자 (const)
문제
다음 코드는지도를 전달한다고 말합니다 const
로 operator[]
메소드는 한정자를 폐기합니다.
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MapWrapper {
public:
const int &get_value(const int &key) const {
return _map[key];
}
private:
map<int, int> _map;
};
int main() {
MapWrapper mw;
cout << mw.get_value(42) << endl;
return 0;
}
맵 액세스에서 발생할 수있는 할당이 발생했기 때문입니까? 맵 액세스가있는 기능이 Const로 선언 할 수 없습니까?
MapWrapper.cpp:10: error: passing ‘const std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >’ as ‘this’ argument of ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = int, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, int> >]’ discards qualifiers
해결책
std::map
'에스 operator []
다음과 같이 선언되지 않습니다 const
, 그 행동 때문일 수 없습니다.
T & Operator [] (Const Key & Key)
키와 동등한 키에 매핑 된 값에 대한 참조를 반환하며, 이러한 키가 아직 존재하지 않는 경우 삽입을 수행합니다.
결과적으로 기능을 선언 할 수 없습니다 const
, 지도를 사용하십시오 operator[]
.
std::map
'에스 find()
함수를 사용하면 맵을 수정하지 않고 키를 찾을 수 있습니다.
find()
반환합니다 iterator
, 또는 const_iterator
an std::pair
두 키를 모두 포함하는 (.first
) 및 값 (.second
).
C ++ 11에서는 사용할 수도 있습니다 at()
~을 위한 std::map
. 요소가 존재하지 않으면 함수는 a로 던져집니다 std::out_of_range
예외,와 달리 operator []
.
다른 팁
당신은 사용할 수 없습니다 operator[]
지도에 const
그 방법은 그렇지 않습니다 const
맵을 수정할 수 있으므로 _map[key]
). 사용해보십시오 find
대신 방법.
부터 operator[]
Const-volified Overload가 없으며 Const- 자격 기능으로 안전하게 사용할 수 없습니다. 이것은 아마도 현재 과부하가 주요 값을 반환하고 설정한다는 목표로 구축 되었기 때문일 것입니다.
대신 사용할 수 있습니다.
VALUE = map.find(KEY)->second;
또는 C ++ 11에서는 at()
운영자:
VALUE = map.at(KEY);
GCC 헤더의 새로운 버전 (내 컴퓨터에서 4.1 및 4.2)에는 비표준 멤버 함수 맵 :: at ()가 const로 선언되고 키가 맵에 있지 않은 경우 std :: out_of_range를 던지고 있습니다.
const mapped_type& at(const key_type& __k) const
함수 주석의 참조에서 이것은 표준 라이브러리에서 새로운 멤버 함수로 제안 된 것으로 보입니다.
먼저, _로 시작하는 기호를 사용해서는 안됩니다. 언어 구현/컴파일러 라이터에 예약되어 있기 때문입니다. _map이 누군가의 컴파일러에서 구문 오류가되기가 매우 쉬울 것이며, 당신은 자신을 비난 할 사람이 없을 것입니다.
밑줄을 사용하려면 시작이 아니라 끝에 놓으십시오. 당신은 아마도 마이크로 소프트 코드가 그것을하는 것을 보았 기 때문에 아마도이 실수를했을 것입니다. 그들은 자신의 컴파일러를 작성하므로 그것을 벗어날 수 있습니다. 그럼에도 불구하고 그것은 나쁜 생각입니다.
연산자 []는 참조를 반환 할뿐만 아니라 실제로지도에서 항목을 만듭니다. 따라서 당신은 단지 매핑을 얻는 것이 아니라, 아무것도 없다면, 당신은 하나를 만들고 있습니다. 그것은 당신이 의도 한 것이 아닙니다.