2011-03-14 13 views
1
class Demo { 
    struct FileData { 
     int size; 
     BYTE* buffer; 
     DWORD flags; 
    }; 

    typedef std::tr1::unordered_map<std::wstring,FileData> FileMap; 
    FileMap m_fileMap; 

    void myFunc() 
    { 
     std::wstring name = L"TestFile.png"; 
     FileMap::const_iterator iter = m_fileMap.find(name); 
     std::cout << iter->first; 
    } 
}; 

위의 코드를 살펴보십시오. 내 문제는 어떻게 FileMap :: const_iterator 작동합니다. 키 (std :: wstring) 및 값 (FileData)의 복사본을 만드나요? 아니면 그것은 단지 포인터와 키와 값에 대한 참조를 가지고 있습니까?C++ STL unordered_map 반복자 문제

답변

3

반복자를 할당 할 수 있으며지도의 키와 값은 복사 가능해야하며 할당 할 필요는 없습니다.

따라서 일반적으로 복사본을 사용할 수 없으므로 내부적으로 포인터 또는 참조를 보유해야합니다.

경우에 따라서는 ints를 사용하여 어쨌든 사본을 전문화하고 사용할 수 있습니다.

1

보증은 없습니다. 그러나 반복기가 포인터를 보유 할 가능성이 큽니다. 변경할 수있는 반복자를 사용하면 데이터를 수정할 수 있으므로 복사본이 만들어지지 않으며 const 버전을 사용할 때 복사본을 만드는 이유를 생각할 수 없습니다.

그러나 이러한 고려 사항에 따라 코드를 작성 하시겠습니까? 아니면 호기심에서 벗어나니까?

+0

글쎄, 실제로 나는 그것이 작동하는 방법에 대한 그냥 궁금했다. 그래서'std :: tr1 :: unordered_map fileMap; '을 사용하는 것이 키와 값의 복사본을 만들지 않기 때문에 효율적이라는 것을 확신합니다. – MorrisLiang

+0

그것에 대해 많이 생각하면 안됩니다. 컴파일러는 많은 복사본을 최적화합니다. 따라서 복사본을 피하려고하면 많은 경우 컴파일러가 손실되고 최적화되지 않으므로 코드가 복잡해지고 컴파일러가 느려질 수 있습니다. –

0

unordered_map에는 키 값 (값) 한 쌍이 들어 있고, const_iterator에는 해당 쌍에 대한 포인터가 들어 있습니다. ->로 멤버에 액세스하여 이터레이터를 참조 해제합니다.

1

반복자 & const_iterator 데이터에 대한 포인터를 보유하십시오. 값이 발견되지 않으면 m_fileMap.end()를 반환해야합니다.

2

관련 컨테이너 :
이것은 내부적으로 키/값 쌍을 저장한다는 것을 의미합니다 (value_type을 참조 함).

제공되는 반복기는 * 및 -> 연산자를 오버로드하여 value_type에 대한 참조를 제공합니다. 성병 :: 쌍

어느 따라서 당신이 시도 할 수 있습니다 :

FileMap::const_iterator iter = m_fileMap.find(name); 
if (iter != m_fileMap.end()) 
{ 
    FileMap::value_type const& value = *iter; 

    FileMap::key_type const& key = iter->first; /* value.first */ 
    FileMap::data_type const& data = iter->second; /* value.second */ 

    // Alternatively: 
    // Assuming this hold: typedef std::tr1::unordered_map<std::wstring,FileData> FileMap; 
    std::wstring const& key1 = iter->first; 
    FileData  const& data1 = iter->second; 
} 
+0

글쎄, 어떻게 사용하는지 압니다. 그러나 장면 뒤에는 반복기 관리자가 리소스를 어떻게 사용합니까? iter-> first는 std :: wstring (여기의 키)의 복사본입니까? 왜냐하면 그렇게한다면 그것은 성능을 해칠 것입니다. – MorrisLiang

+0

@ Morris : 연산자 없음 -> 두 멤버 (첫째, 둘째)가있는 'value_type'에 대한 포인터를 반환합니다. 'value_type'에 대한 참조이므로 no 키가 복사됩니다 (명시 적으로 복사를하지 않는 한 (예 : 변수에 할당)). PS 대부분의 STL 구현은 문자열 복사가 상대적으로 저렴하도록 최적화되어 있습니다. –

+0

이제 모든 물건에 대한 아이디어를 얻었습니다. 컨테이너는 내부에있는 것들을 value_type으로 저장합니다. iterator는 value_type을 가리키는 포인터와 같다. 그래서 어떤 사본도 포함되지 않을 것입니다. – MorrisLiang