【问题标题】:Why does std::move take rvalue reference as argument?为什么 std::move 将右值引用作为参数?
【发布时间】:2017-12-17 05:05:18
【问题描述】:

根据cppreference.com,move有签名

template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept;

为什么它需要一个右值引用 T&amp;&amp; t 作为它的参数?

当我尝试以下代码时

void foo(int&& bar) {
    cout << "baz" << endl;
}

int main(){
    int a;
    foo(a);
}

我从编译器收到一个错误“右值引用不能绑定到左值”

发生了什么事?我很困惑。

【问题讨论】:

  • 您假设T&amp;&amp; t 是一个右值引用。这还为时过早,在您知道 T 是什么之前,没有办法说 T&amp;&amp; t 是否是 rvlaue 引用。在推导T时,特意设计了语言规则(类型推导和引用折叠),使T&amp;&amp; t根据外部情况在右值和左值引用之间切换。
  • 令人困惑。根据上下文,双放大器 && 具有两种含义中的任何一种。在模板参数上,它表示“转发引用”。

标签: c++ c++11 move rvalue-reference forwarding-reference


【解决方案1】:

它不是右值引用,而是forwarding reference;这可以保留参数的值类别。这意味着std::move 可以同时接受左值和右值,并无条件地将它们转换为右值。

转发引用是一种特殊的引用,它保留函数参数的值类别,从而可以通过 std::forward 转发它。转发引用是:

1) 声明为右值的函数模​​板的函数参数 引用相同的 cv 非限定类型模板参数 函数模板:

2) auto&& 除非从大括号括起来的初始化列表中推导出来。

另一方面,int&amp;&amp; 是一个右值引用;注意这里的区别,如果函数模板参数的类型为T&amp;&amp;,模板参数为T,即推导类型T,则该参数为转发引用。

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 1970-01-01
    • 2019-07-23
    • 2020-05-25
    • 2014-02-16
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多