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

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

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

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

于 2013-03-29T10:08:58.753 回答