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

Dan*_*rey 8 c++ std language-lawyer c++11

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

#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!
}
Run Code Online (Sandbox Code Playgroud)

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

And*_*owl 10

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

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

短语"等价键"是指比较而不是operator==开键所施加的等价关系 .即,两个键k1和k2被认为是等价的,如果为比较对象comp,comp(k1, k2) == false && comp(k2, k1) == false.对于任何两个键k1和k2同一个容器,调用comp(k1, k2)应始终返回相同的值.

  • @DanielFrey:我不知道,但在我看来,整个标准倾向于将相关句子埋在他们很难发现的地方;) (5认同)