2012-11-12 2 views
1

는 동안 키가 존재하지 않는 경우에만지도를 삽입 할 수있는 효율적인 방법을 찾고, 나는 this approach 건너 온 : std::map 잘 작동삽입하기 전에 lower_bound를 사용하여지도를 검색 할 때의 이점. ptr_map과 동일합니까?

MapType::iterator lb = mymap.lower_bound(k); 

if(lb != mymap.end() && !(mymap.key_comp()(k, lb->first))) { 
    // key exists. Value accessible from lb->second 
} else { 
    // Do insert. Use lb as a hint to insert so it can avoid another lookup 
    mymap.insert(lb, MapType::value_type(k, v)); 
} 

. 그러나, boost::ptr_map은 유사한 형태, 즉 반복자 위치를 허용하는 형태를 제공하지 않는다.

그래서 궁금하네요 :

  1. 그 접근 방식의 장점은 똑바로 앞으로 삽입을하고 어떻게 비교이야? 즉

    std::pair<MapType::iterator, bool> ret; 
    ret = mymap.insert(MapType::value_type(k, v)); 
    if (!ret.second) { 
        // key exists. insertion not done. do something else 
    } 
    
  2. lower_bound 방법을 사용하는 좋은 이유가 실제로 있다면, 그것은 boost::ptr_map에 상응하는 전략이있다? 아니면 적용되지 않겠습니까?

답변

1

이렇게하는 데 가장 효율적인 두 가지 방법이 있습니다.

첫 번째 효율적인 방법은 insert (STL에서도 마찬가지 임)을 호출하는 것입니다. 이는 pair<iterator,bool>을 반환하므로 이미 존재하는 경우 삽입되지 않습니다.

키가 존재하지 않는 경우 개체를 만들어야 할 때 사용하는 두 번째 방법은 operator[]을 사용하여 거기에 대한 참조를 반환하는 것입니다. 항목이 없으면 기본 생성 값으로 사용자를 대신하여 삽입합니다.

차이점은 다음과 같습니다. 포인터에 대한 일반 STL 맵의 경우 operator[]이 포인터를 반환하고 널 포인터를 삽입합니다. boost::ptr_map의 경우 null 포인터를 삽입하지 않으며 기본 생성 개체에 대한 포인터를 삽입합니다.

컬렉션에 실제로 기본 생성 개체가 포함되어 있고 삽입하려는 개체가 아직없는 경우 한 번에 효율적으로 작업 할 수있는 방법을 찾을 수 없습니다. 이 경우이 컬렉션을 사용하지 않거나 개체가 약간 수정되어 "기본 구성"즉 null 상태 일종의 플래그를 표시해야합니다.

+0

흥미롭게도, 내가 물어보기 4 분 전에이 질문에 처음 대답 한 것으로 나를 보여주고 있습니다. – CashCow

+0

많은 감사. 첫 번째 제안은 제가 예제에서 인용 한 접근 방식을 찾을 때까지 실제로 사용했던 것입니다. 두 접근법을 비교하려고 시도했을 때,'ptr_map'으로 풀리지 않았습니다. 내 원래의 질문은별로 잘 쓰여지지 않았고 오해의 소지가 조금있었습니다. 지금 업데이트되었습니다. 죄송합니다. –

+1

"가장 효율적"이라는 단어는 논쟁의 여지가 있습니다. 이는 유스 케이스에 달려 있습니다. 삽입 할 객체를 생성하는 것은 매우 많은 비용이 소요될 수 있으므로, 먼저 'lower_bound'가 작동 할 수있는 곳을 먼저 확인해야합니다. –