为什么不修改关联容器的键?

时间:2013-03-29 10:05:52

标签: c++ c++11 std language-lawyer

我知道在关联容器中更改对象的键是一个可怕的想法,但我想知道标准到底禁止我这样做。考虑:

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

我认为上面的应该是非法的,但我现在正在阅读标准已有一段时间了,而且我找不到任何实际使非法的内容。它在哪里?或者它是否隐藏在未来的缺陷报告中?

1 个答案:

答案 0 :(得分:10)

如果您根据指定的比较器更改后任意两个键的比较不同,则会在程序中注入未定义的行为。

根据C ++ 11标准的第23.2.4 / 3段([associative.reqmts]):

  

短语“等价键”是指比较所强加的等价关系,而不是   密钥上的operator==。也就是说,如果进行比较,则认为两个键k1k2是等效的   对象compcomp(k1, k2) == false && comp(k2, k1) == false对于任意两个键k1k2   同一个容器,调用comp(k1, k2)应始终返回相同的值。