如何获得对右值的引用?

时间:2015-02-11 15:51:25

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

我在C ++中使用过std::movestd::forward。我的问题是:标准库实际上如何实现这些功能?

如果左值是你可以得到的地址,而右值不是左值,你怎么能实际实现这些参考?

这些新设施是否允许以下​​内容:

auto x = &(3); 

或类似的东西?你能获得一个不仅仅是std::move / forward返回左值的右值的引用吗?

希望这些问题有意义。我无法在Google上找到有关完美转发的教程,等等。

3 个答案:

答案 0 :(得分:9)

  

如何获得对 rvalue 的引用?

从概念上讲, rvalue 表达式会创建一个临时对象,或者有时表示一个现有对象。这可以像任何其他对象一样绑定到引用;但是,为了避免混淆,该语言仅允许 rvalue const lvalue 引用。

  

我在C ++中使用过std :: move和std :: forward。我的问题是编译器实际上是如何实现的?

move只返回对其参数的 rvalue 引用,相当于

static_cast<typename remove_reference<T>::type&&>(t)

函数调用的结果是 rvalue (特别是 xvalue ),因此它可以绑定到 rvalue 引用,其中函数论证不可能。这允许您明确地从左值移动,使用move将其转换为 rvalue ,同时不允许您意外地从它移动。

forward类似,但已重载以返回 rvalue rvalue rvalue 引用的引用,以及左值引用其他任何内容。

  

如果l值是你可以得到的地址

这或多或少是正确的。官方定义是表达式&#34;指定一个函数或一个对象&#34;,那些是具有地址的东西。

  

并且r值专门不是l值

不是真的。稍微简化,表达式可以是左值右值,但可以从一个转换为另一个。 左值可以隐式转换为 rvalue ;转换另一种方式可以使用强制转换完成,如move所做的那样。

  

你怎么能实际实现这些引用?

就像任何其他引用一样 - 作为它所绑定的对象的别名或指针。唯一的区别是哪种表达式可用于表示(并可能创建)绑定到引用的对象。

  

这些新设施是否允许auto x = &(3);

之类的内容

试图直接获取 rvalue 的地址,这是不允许的。由于问题是关于引用而不是指针,因此允许以下内容,绑定对临时对象的引用(其生命周期被扩展以匹配引用):

auto && rvalue = 3;
auto const & const_lvalue = 3;

虽然不允许将其绑定到非const 左值引用

auto & lvalue = 3;  // ERROR

答案 1 :(得分:4)

我无法调用函数:void foo(string* bar)这样:foo(&string("Hello World!"))或者我收到错误:

  

错误:获取临时

的地址

我也无法调用函数:void foo(string& bar)这样:foo(string("Hello World!"))或者我收到错误:

  

错误:'std :: string&amp;类型的非const引用的初始化无效来自'std :: string {aka std :: basic_string}'类型的右值的{aka std :: basic_string&amp;}'

C ++ 11为我提供的功能是制作一个右值引用,因此我可以调用一个函数:void foo(string&& bar),如下所示:foo(string("Hello World!")); < / p>

此外,在内部foo可以获取由右值引用传入的对象的地址:

void foo(string&& bar){
    string* temp = &bar;

    cout << *temp << " @:" << temp << endl;
}

看起来OP对rvalues有很好的控制力。但this explanation of them对我有帮助,也可能对其他人有帮助。它详细介绍了为什么C ++ 03允许对rvalues进行常量引用,而不是C ++ 11的右值引用。

答案 2 :(得分:1)

基本上,编译魔术。标准描述了规则,编译器制造商只需要弄清楚如何实现规则。

实际上,引用要么被优化掉,要么作为CPU级别的指针实现。

在这个意义上,{p> std::move并不是特别的。它有一个左值引用作为输入,右值引用作为输出。编译器只需将rvalue引用规则应用于输入。

同样,std::forward<T>的目标只是告诉编译器将一组不同的规则应用于参数,这些规则恰好被定义以便完美转发起作用。该功能本身没有任何作用。