2013-03-29 1 views
8

연관 컨테이너에서 객체의 키를 변경하는 것은 끔찍한 생각이지만, 표준에서 내가 그렇게하는 것을 정확히 금지하고 있는지 궁금합니다. 고려 :왜 연관 컨테이너의 키를 수정하지 않습니까?

#include <map> 
#include <memory> 

struct X { int i; }; 

struct lt 
{ 
    bool operator()(const std::shared_ptr<X>& lhs, 
        const std::shared_ptr<X>& rhs) const 
    { 
    return lhs->i < rhs->i; 
    } 
}; 

int main() 
{ 
    std::map< std::shared_ptr<X>, int, lt > m; 
    auto x = std::make_shared<X>(); 
    x->i = 1; 
    m.insert(std::make_pair(x, 2)); 

    x->i = 42; // change key wrt the container! 
} 

나는 위의 불법해야한다고 생각하지만, 지금은 약간의 시간에 대한 표준을 읽고 있던 나는 실제로 불법하게 아무것도 찾을 수 없습니다. 어디 있니? 아니면 미래의 결함 보고서에 숨어 있습니까?

+0

std :: map에는 트리 내부 구조가 있습니다. 키를 수정하면 내부 구조가 올바르지 않고 잘못된 경로로 이동하기 때문에 검색이 작동하지 않습니다. – Felics

+0

@Felics : 그것은 질문이 아니 었습니다. –

+0

S. Meyers의 "Effective STL"에는이 문제에 대한 전체 장이 나와 있습니다 (항목 22 참조). 재미있는 점은 맵의 내부 구조를 뒤 틀리는 것은 어렵지만 (맵의 요소 유형은'pair '입니다.), 그 일종의 앨리어싱을 사용해야합니다. ** 매우 난파하기 쉽습니다 ** set과 multiset을 가지고 있습니다. 왜냐하면'it'이 (multi) set :: iterator 일 때'* it'에 할당 할 수 있기 때문입니다. – shakurov

답변

9

지정한 비교 자에 따라 변경 한 후에 두 키의 비교가 다른 방식으로 값을 수정하면 정의되지 않은 동작이 프로그램에 삽입됩니다. 문단 C++ 11 표준의 23.2.4/3 당

([associative.reqmts])

어구는 "키 당량"은 비교 아닌 의해 부과 동치 관계를 의미 operator== 키. 즉, k1k2의 두 키는 비교 대상이 인 경우 comp, comp(k1, k2) == false && comp(k2, k1) == false 인 경우 동등한 것으로 간주됩니다. 동일한 컨테이너에 에있는 k1k2 두 개의 키에 대해 comp(k1, k2)을 호출하면 항상 동일한 값이 반환됩니다.

+0

죄송합니다. 못 봤어. : D – Nawaz

+1

+1 그리고 받아 들였습니다. 그러나 강조 표시된 문장이 왜 자신의 글 머리 기호가 아닌 "키의 등가성"이라는 맥락에서 묻혀 있었습니까? 이상한. –

+5

@DanielFrey : 잘 모르겠지만, 표준 전체가 관련 문장을 어딘가에 묻어 버리는 경향이 있습니다.) –

관련 문제