【问题标题】:Why does QMap::operator[](const Key & key) return by value?为什么 QMap::operator[](const Key & key) 按值返回?
【发布时间】:2013-09-01 11:01:18
【问题描述】:

我注意到QMap::operator[](const Key & key) 有这两个overloads

    T & QMap::operator[](const Key & key)
const T QMap::operator[](const Key & key) const

按价值退货有理由吗?

因为我们有移动语义:

当按值返回时,我们是否应该按 const 值返回?

我问的原因是这样的:

想象一下我们有:

class ExpensiveToCopy;
{
public:
    int someProperty() const;
    ...
}

void f(const QMap<int, ExpensiveToCopy>& map)
{
    int lala = map[4].someProperty(); // We need to copy the entire object
                                      // just to look at someProperty();
}

【问题讨论】:

  • 只有一个重载按值返回,另一个返回引用。
  • @Joachim 是的,那是我不明白的事情。他们不应该都返回一个引用,例如 std::vector::operator[] 吗?
  • @nurettin 它确实禁止移动语义。
  • 返回一个常量值确实阻止移动。移动构造函数更快因为它们被允许改变原始值,所以 const 会阻止它。
  • 您需要在示例中使用const QMap&lt;int, ExpensiveToCopy&gt; map; 来触发const 重载。

标签: c++ qt c++11


【解决方案1】:

const 的情况下,如果const 映射中尚不存在元素,则我们无法将其添加到该映射中,因此将返回一个本地对象。

否则,在非const 的情况下,将使用指定的键(如果还没有)创建一个元素,然后返回对它的引用。

【讨论】:

  • 就是这样。我正要写同样的答案。注意std::map 没有const operator[],这可能是件好事。不那么混乱。
  • 特别是:const 案例必须能够返回一个“默认”构造的元素,而无需在地图中插入任何内容,以防在地图中找不到具有给定键的元素。所以它不能返回引用。
  • @juanchopanza 它可​​以返回对静态局部变量的引用,因此可以返回 const 引用。想不想,是另外一回事……
  • @Sjoerd 是的。此外,这并不能解释为什么返回 const 值。我认为 const 重载是个坏主意,除非您愿意引入绑定检查。
  • @juanchopanza 他们可能将值设置为const,这样就不会发生const_map['k'].someMutatingMemberFn() 之类的事情,其目的是修改地图中包含的对象,而不是临时对象,这是有道理的在 C++98 中,但在 C++11 中是一个坏主意(因为它阻止了移动)。通过引用限定符在 C++11 中仍然可以防止这种滥用。另见stackoverflow.com/questions/16834937/…
【解决方案2】:

我认为非引用const 是为了确保客户端代码不能以任何方式修改map。你知道如果使用const_cast&lt;ExpensiveToCopy&gt;map[4]或者其他方式,我们仍然可以修改map[4],但是这个map[4]不是引用map的第4个元素。

【讨论】:

    【解决方案3】:

    也不可能存储带有 const 成员的 Value 类型,因为按值返回需要 Value::operator=()。在我看来,QMap::operator[] 的 const 版本构思不当。调用 contains() 和 at() 可以产生相同的效果。这是一个很不方便的便利函数示例。

    【讨论】:

      猜你喜欢
      • 2015-02-25
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 2010-11-10
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多