2013-06-11 1 views
2

C++ 표준 라이브러리의 std :: map 클래스를 사용하여 재생하고 요소를 지우고 참조하려고하면 아래 코드에서 주석 처리 된 행이 나타납니다), 요소는 0의 값으로 되돌아 올 것이다. 이것은 예상 되는가? 존재하지 않는 요소를 우연히 만들지 않고 실제로 요소에 액세스하려면 find 함수를 사용해야합니까?참조 할 경우 C++ map 요소가 지워지지 않습니다.

컴파일러 설정 : osx 10.8.3에서 g ++로 컴파일합니다. i686-apple-darwin11-llvm-g ++ - 4.2 (GCC) 4.2.1 (Apple Inc. 빌드 5658 기준) (LLVM 빌드 2336.11.00)

using namespace std; 

map<int,int> myMap; 
map<int,int>::iterator it; 

myMap[1] = 5; 

for (it=myMap.begin(); it!=myMap.end(); ++it) 
    std::cout << it->first << " => " << it->second << '\n'; 

printf("map test result: %d\n", myMap[1]); 

it = myMap.find(1); 
myMap.erase(it); 

// If I uncomment this it will cause a 0 value to occur at key 1. 
//printf("map test result: %d\n", myMap[1]); 

if (myMap.find(1) == myMap.end()) 
    puts("element key 1 is null, ok"); 
else 
    puts("element @ key 1 exists, error"); 

if (myMap.empty()) 
    puts("map is empty"); 
else 
    puts("map is not empty, error"); 

for (it=myMap.begin(); it!=myMap.end(); ++it) 
    std::cout << it->first << " => " << it->second << '\n'; 

내가 주석 번째의 printf 라인이를 실행하면 그냥 예상대로 실행 명확히하기 :

1 => 5 
map test result: 5 
element key 1 is null, ok 
map is empty 

내가 줄을 주석 실행하는 경우에는 myMap의 접근 [1] printf 문에서 다른 요소를 만들고 결과는 다음과 같습니다.

1 => 5 
map test result: 5 
map test result: 0 
element @ key 1 exists, error 
map is not empty, error 
1 => 0 

답변

5

예, 여기가 operator[]std::map입니다. 규격 (C++ 11 §23.5.4.3)에서 :

mapped_type& operator[](const key_type& k); 
mapped_type& operator[](key_type&& k); 

[...]

효과 다음 unordered_map도 이미 그 키 K와 등가 인 요소를 포함하지 않으면 첫 번째 연산자는 값 value_type(k, mapped_type())을 삽입하고 두 번째 연산자는 값 value_type(std::move(k), mapped_type())을 삽입합니다.

요소가 삽입 된 다음 지워진 적이없는 경우에도 발생합니다. operator[]을 사용하는 요소 액세스는 존재하지 않는 키에 적용 할 때 새로 생성 된 기본값 구성 값을 삽입하기 만합니다.

find 기능을 사용하시는 것이 가장 좋습니다. std::map. 키가 존재하지 않으면 end -iterator를 반환합니다.

2

예, 예상되는 동작입니다. 사양을 읽기 이외에, 당신은 유형 서명에서이를 추론 할 수 있습니다

T& operator[] (const key_type& k); 
operator =는 반환 값에 호출되기 때문에 당신이 [] 후, 키에 할당 될 겁니다 경우는 말할 수 없다

연산자가 이미 실행을 마쳤습니다. 메소드가 빈 값을 표현할 방법이 없습니다. 포인터가 아닌 참조를 리턴합니다.

+1

+1 (이론적으로 맵은 일종의 더미 요소에 대한 참조를 반환 할 수 있지만 이상한 디자인이지만 불가능하지는 않습니다.) – jogojapan

+1

그것이 작동하는 방식으로 지금은 카운터 또는 컨테이너 맵에 적합합니다. map [key] ++ 또는 map [key] .push_back (value)은 java와 같이 이것을하지 않는 언어에서 동급보다 훨씬 깔끔합니다. – Bwmat

+0

@jogojapan 실로! 물론'T'가'std :: map '에서주는 것과 동일한'T'인지 확인함으로써 검사 할 수 있습니다. –

관련 문제