2010-03-17 9 views
4

에 대한 다음 코드는 잘 작동 :는 []지도

std::map<int, int>& m = std::map<int, int>(); 
int i = m[0]; 

하지만 다음 코드 : 대부분의 시간

// error C2678: binary '[' : no operator... 
const std::map<int, int>& m = std::map<int, int>(); 
int i = m[0]; 

을, I

http://www.javapractices.com/topic/TopicAction.do?Id=29

: 내 물건의 대부분 인해 이유로, 불변이 될 수 있도록하는 것을 선호 맵 소스 코드를 봅니다. 따라서이 const 멤버 함수가 될 수 없습니다, 키가 발견되지 않으면 할 수없는 표준 : :지도

const mapped_type& operator[](const key_type& _Keyval) const 
+2

이제 Roger Pate가 잘못된 답변을 내게 바로 설정 했으므로 더 흥미로운 질문을 던집니다. 왜 '연산자'의'const' 버전을 던지거나 (또는 ​​정의되지 않은 동작을하는지) 엔트리가지도에 없다면? –

+0

@ 마이클 : 나는 완전히 동의한다. 나는 "잘 사용하고 찾기 만하면!"이라고 생각한 적이 없다. 많은 대답이었습니다. 서투른입니다. 'at'가'vector'에 예외를 던졌습니다. 왜 cant' 연산자 [] const'가'map'에서 예외를 던집니까? – GManNickG

답변

4

operator []는지도에없는 항목을 만듭니다. 연산자가 const 맵에 구현 된 경우에는 불가능합니다. 이 에 주어진 설명입니다

지도를 첨자 키를 찾을 수없는 경우 기본 요소를 추가합니다. 따라서 const 맵에는 operator [] 버전이 없습니다. 또한 mapped_type (값 유형)에 기본값이있는 경우에만 하위 스크립트를 으로 사용할 수 있습니다. 프로그래머가 키가 있는지보고 싶다면 find() 작업 (17.4.1.6)을 사용하여 맵을 수정하지 않고 키를 찾을 수 있습니다.

1

연산자 [] 삽입을 제공하는 어떤 이유가 있나요

mapped_type& operator[](const key_type& _Keyval) 

있습니다.

6

이유는 존재하지 않는 키의 요소에 액세스하려고 시도 할 때 기본 생성 요소로 키가 만들어지기 때문에 std::map 의미입니다. 즉, m[0]은 아직 존재하지 않는 경우 위치 0에 int를 작성합니다. 분명히 const 맵과 호환되지 않습니다.

당신은 "잘 const 버전의 operator[]을 만들 수 있습니다!"라고 말할 수는 있지만 두 가지 문제가 있습니다 : 의미론의 차이는 명확하지 않고 혼란스럽고 명확하지 않습니다. 존재하지 않는 키에 액세스하려고하면 예외가 발생합니다.

대신지도에서 find() 메서드를 사용하면 찾고있는 키/값 쌍을 가리키는 반복자가 반환됩니다. 조회는 정확히 operator[]만큼 효율적이며 const 맵 (이 경우에는 const 반복자를 반환)에서 사용할 수 있으며 키가 존재하지 않으면 end() 반복자를 반환합니다.

+0

나는이 사용자가 보여 주듯이 혼란 스럽기 때문에'confusing' 인수에 가입 할 확신이 없습니다. 그리고'map.find (key) -> second'는'map [key]'만큼 좋지 않습니다. 모든 '정의되지 않은'동작이 이미있는 상태에서 하나 이상은 다시 정리되지 않을 것입니다. p –

+0

여기서 정의되지 않은 동작을 허용하는 것은 알 수없는 내용의지도를 사용하면 검색하기 전에 먼저 확인해야합니다. 특히 현명한 사용 패턴이 아닐 수도 있습니다. – visitor

+0

@Matthieu 나는 현재의 행동이 * 직관적 인 것이 아니라는 것에 동의하지만, 그것이 무엇인지 알게되면 일관되고 따라서 혼란스럽지 않다. 'operator '의 두 가지 버전을 가지고 있는데, 그 중 하나는 항상 작동하도록 보장되고, 다른 하나는 예외를 던지거나 어떤 상황에서는 정의되지 않은 동작을 야기 할 수 있으며 유일한 차이점은 기본 객체가 const인지 아닌지, 다른 곳에서 변수의 상수를 변경하면 컴파일 타임 오류 또는 경고를 발생시키지 않고 프로그램의 동작을 크게 바꿀 수 있기 때문에 혼란 스러울 수 있습니다. –

2

불변 버전이 있으며 find()이라고합니다.