【问题标题】:Impact of returning const value types in C++11 on move semantics在 C++11 中返回 const 值类型对移动语义的影响
【发布时间】:2013-04-01 14:31:15
【问题描述】:

我不清楚返回 const 值对 C++11 中移动语义的影响。

这两个返回数据成员的函数有什么区别吗? const 在 C++11 中仍然是多余的吗?

int GetValueA() { return mValueA; }
const int GetValueB() { return mValueB; }

这些功能呢?

int GetValuesAB() { return mValueA + mValueB; }
const int GetValuesCD() { return mValueC + mValueD; }

【问题讨论】:

标签: c++ c++11 constants move-semantics


【解决方案1】:

调用按值返回的函数的表达式是纯右值。但是,没有非类非数组类型的const prvalues (§5/6):

如果纯右值最初的类型为“cv T”,其中T 是 cv 非限定的非类、非数组类型,则表达式的类型在进一步调整之前调整为 T分析。

这意味着您对函数的两个定义之间没有区别。它是否返回 const int 或仅返回 int 无关紧要,因为表达式永远不是 const

但是,当您返回类类型时会有所不同。考虑以下示例:

struct foo
{
  void bar() { std::cout << "Hello" << std::endl; }
};

foo get_foo();

现在,如果我们调用get_foo(),我们会得到一个临时的foo 对象。这个prvalue不是const,我们可以在上面调用非const的成员函数,所以我们可以很高兴地做get_foo().bar()。但是,我们可以像这样更改get_foo 的声明:

const foo get_foo();

现在,表达式get_foo() 是一个const prvalue(这是允许的,因为它是一个类类型),我们不能再在它返回的临时对象上调用bar

尽管如此,谈论非类类型的移动语义是没有意义的,因为int 永远不会被移动。如果你返回一个const 类类型,那也不能被移走,因为它是const。演示:

foo get_foo();
foo f(get_foo()); // Will call the move constructor

const foo get_foo();
foo f(get_foo()); // Will call the copy constructor

这是因为const prvalue 不会绑定到非const 右值引用,移动构造函数将其作为参数。

【讨论】:

  • 如果 void bar()void bar() const 我们可以在临时对象上调用它吗?
  • @M.Dudley 是的,你会的。我刚刚添加了一些关于移动语义的内容,因为我忘记了我原来的答案。
  • foo( foo const&amp;&amp; f ) 移动构造函数来救援? (就像有超过 1 个复制构造函数一样......)
  • @Yakk 那么您将无法从f 移动,因为它是const
  • struct foo { mutable std::unique_ptr&lt;int&gt; ptr; foo( const foo&amp;&amp; o ):ptr(std::move(o.ptr)) {};}; 学究不同。 :)
猜你喜欢
  • 1970-01-01
  • 2016-11-11
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多