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!
}

上記違法であると思いますが、しばらくの間標準を読んでいましたが、実際に違法となるものは何も見つかりませ。それはどこにある?それとも、今後の不具合報告に隠れているのでしょうか?

4

1 に答える 1

10

これにより、指定したコンパレータに従って変更後に任意の 2 つのキーの比較が異なるように値を変更すると、プログラムに未定義の動作が挿入されます。

C++11 標準 ([associative.reqmts]) のパラグラフ 23.2.4/3:

「キーの等価性」という語句は、キーではなく、比較によって課せられる等価関係を意味 operator==します。つまり、2 つのキーk1k2は、比較対象comp,の場合、同等と見なされますcomp(k1, k2) == false && comp(k2, k1) == false同じコンテナー内の任意の 2 つのキーに対してk1k2呼び出しcomp(k1, k2)は常に同じ値を返します。

于 2013-03-29T10:08:58.753 に答える