2013-03-29 8 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'が(複数の)set :: iteratorのときに' * it'に代入することができます。 – shakurov

答えて

9

これは、指定したコンパレータに応じて変更後に2つのキーの比較が異なるように値を変更した場合、未定義動作をプログラムに挿入します。 C++ 11標準([associative.reqmts])のパラグラフ23.2.4/3当たり

語句「鍵の等価」と比較しないことによって課される同値関係を意味キーの operator==すなわち、​​とk2の2つのキーは、比較の場合、 オブジェクトcompcomp(k1, k2) == false && comp(k2, k1) == falseの場合、同等とみなされます。 同じ容器の​​とk2の2つのキーについては、comp(k1, k2)を呼び出すと常に同じ値が返されます。

+0

それを見ていない。 :D – Nawaz

+1

+1そして受け入れられましたが、強調された文章はそれ自身の箇条書きではなく、代わりに「鍵の等価性」の背景に埋もれていましたか?奇妙な。 –

+5

@DanielFrey:私はスタンダード全体が関連する文章をどこかに見つけにくいところに埋もれているようですが、 –

関連する問題