std :: unordered_map operator []가 비 기존 키에 대해 0으로 초기화합니까?


25

cppreference.com에 따르면 std::map::operator[]존재하지 않는 값에 대해서는 초기화가 수행되지 않습니다.

그러나 동일한 사이트에는 이에 대한 std::unordered_map::operator[]예제가있는 경우를 제외하고에 대한 0 초기화를 언급하지 않습니다 .

물론 이것은 표준이 아닌 참조 사이트 일뿐입니다. 아래 코드가 정상입니까?

#include <unordered_map>
int main() {
    std::unordered_map<int, int> map;
    return map[42];     // is this guaranteed to return 0?
}

13
@ Ælex 무언가가 초기화되면 확실하게 테스트 할 수 없습니다
idclev 463035818

2
@ Ælex 나는 정말로 이해하지 못한다. 어떻게 초기화되지 std::optional않았는가?
idclev 463035818

2
@ Ælex 초기화 이외의 초기화되지 않은 객체에 대한 작업으로 인해 정의되지 않은 동작이 발생하기 때문에 객체가 초기화되었는지 여부를 테스트 할 방법이 없습니다. std::optional없이 포함 된 값을 보유 개체가 여전히 초기화 된 개체입니다.
bolov

2
값 객체는 0으로 초기화되지 않고 값으로 초기화됩니다. 스칼라 유형의 경우 이들은 동일하지만 클래스 유형의 경우 다릅니다.
aschepler

@ bolov 어제 gnu 17과 std 17을 사용하여 테스트하려고했지만 기괴하게도 내가 가진 것은 초기화가 전혀 없었습니다. 나는 std::optional has_value그것을 테스트 할 것이라고 생각 했지만 실패했지만, 당신이 맞다고 생각합니다.
Ælex

답변:


13

우리가 말하는 과부하에 따라 [unord.map.elem]std::unordered_map::operator[] 과 같습니다 .

T& operator[](const key_type& k)
{
    return try_­emplace(k).first->second;
}

(AN r- 수치 참조 복용 과부하는 이동 ktry_emplace달리 동일)

k지도의 키 아래에 요소가 있으면 try_emplace반복자를 해당 요소와 로 반환합니다 false. 그렇지 않으면 try_emplacekey 아래에 새 요소를 삽입하고 kiterator와 true [unord.map.modifiers]에 반복자를 리턴합니다 .

template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);

우리에게 흥미있는 것은 아직 요소가없는 경우이다 [unord.map.modifiers] / 6 :

그렇지 않으면 다음으로 value_­type구성된 유형의 객체를 삽입합니다.piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...)

(AN r- 수치 참조 복용 과부하는 이동 kforward_­as_­tuple다시 달리 동일하며)

이후 value_typeA는 pair<const Key, T> [unord.map.overview / 2 ,이 새로운지도 요소는 다음과 같이 구성 할 것을 우리에게 알려줍니다 :

pair<const Key, T>(piecewise_­construct, forward_­as_­tuple(k), forward_­as_­tuple(std​::​forward<Args>(args)...));

이후 args에서 나오는 경우 비어 operator[],이 새로운 값은 상기의 구성원으로 구성되는 귀결 pair인수로부터 [pairs.pair] / 14 직접 초기화이다 [class.base.init] / 7 종류의 값의 T이용은 ()이니셜 라이저로서 값 초기화 [dcl.init] /17.4로 요약 됩니다. 의 값 초기화 int는 0 초기화 [dcl.init] / 8 입니다. 그리고 int자연스럽게 int0 으로 초기화 하면 자연스럽게 0 [dcl.init] / 6 으로 초기화 됩니다.

예, 코드는 0을 반환합니다.


21

링크 한 사이트에서 다음과 같이 말합니다.

기본 할당자를 사용하면 키에서 키가 복사되어 매핑 된 값이 초기화됩니다.

소위 int입니다 값 초기화 :

값 초기화의 효과는 다음과 같습니다.

[...]

4) 그렇지 않으면 객체가 0으로 초기화됩니다.

이것이 결과가되는 이유입니다 0.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.