【问题标题】:Is it valid to const_cast the key value of a map?const_cast 映射的键值是否有效?
【发布时间】:2012-11-17 05:31:59
【问题描述】:

长话短说是否有效:

    map<int,int>m;
    m.insert( make_pair( 1, 40 ) );
    for( map<int,int>::iterator it = m.begin(); it != m.end(); ++it )
    {
        const_cast<int&>( it->first ) = 2;
    }

它有效,我在这个问题中遇到过,在实际情况下,映射是两个类的映射,map&lt;classA,classB&gt; 并且要访问该类的非 const 成员,我必须访问const_cast&lt;classA&amp;&gt;(it-&gt;first).NonConstFunction(),这个是我想到的第一个想法,是否可以这样做还是有什么更好的

【问题讨论】:

  • 我不知道具体是在哪里说的,但我很确定它是 const 有充分的理由。
  • 主要的第一个应该是它的地图的关键,问题是这些类有数据类型成员应该在某些时候改变,而带有这些类的地图可能是最好的方式我的解决方案
  • 如果您想要类似的密钥,请使用std::multimap。您所做的事情很危险,因为整个地图在其不知情的情况下拥有相同的密钥!

标签: c++ map iterator constants


【解决方案1】:

这是不允许的。当您像这样就地修改键时,映射将不会“意识到”值已更改,因此它可能需要将该节点移动到它在内部维护的树中的新位置以存储数据。如果树不再排序,那么对树的几乎任何其他操作都可能崩溃和烧毁。

要正确执行此操作,您需要获取键/值对的副本,从映射中删除旧节点,在映射外部修改您的副本,然后将修改后的副本插入回映射中。

【讨论】:

  • 我无法理解第一部分,你能用更非技术性的方式解释一下吗?
  • @ViniyoShouta:地图按顺序维护其包含的项目。当您修改密钥时,它们可能不再按顺序排列。这取决于它们是否有序,所以当/如果它们不是,它将不再正常工作。 unordered_map 不会更好——它基于键的散列存储一个值,因此当您更新键时,它需要重新计算散列并在表中的正确位置插入该散列。
  • 哦,我现在明白了,但是看到,在主要问题中,它使用重载运算符 == 在键值处存储一个类,它在类之间比较的成员保持不变,即使在这种情况会发生吗?
  • @ViniyoShouta: map 使用 operator&lt;,而不是 operator==。如果您有具有相等键的对象比较为不相等(反之亦然),那么整个事情听起来......充其量有点可疑。
  • @ViniyoShouta:如果 ClassA 中有元素根本不参与比较操作,那么修改它们是安全的。将它们声明为mutable(这意味着“即使这个对象是 const,这些成员也可能会改变)。许多人害怕这个构造。
猜你喜欢
  • 2020-05-13
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
  • 2021-11-05
  • 1970-01-01
  • 2019-07-23
  • 2019-08-20
  • 2021-07-13
相关资源
最近更新 更多