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

Why not modify key of associative container?

本文关键字:修改 关联 为什么不      更新时间:2023-10-16

我知道在关联容器中更改对象的键是一个糟糕的主意,但我想知道标准究竟在哪里禁止我这样做。考虑:

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

我认为上述内容应该是非法的,但是我已经阅读了一段时间的标准,我找不到任何真正使其非法的东西。它在哪里?还是隐藏在将来的缺陷报告中?

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

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

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