如何获得对右值的引用?

use*_*764 8 c++ rvalue-reference c++11

我已经使用std::movestd::forwardC++中.我的问题是:这些功能如何通过标准库实际实现?

如果左值是你可以获得的地址,而右值绝对不是左值,你怎么能实际实现这些引用呢?

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

auto x = &(3); 
Run Code Online (Sandbox Code Playgroud)

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

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

Mik*_*our 9

如何获得对右值的引用?

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

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

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

static_cast<typename remove_reference<T>::type&&>(t)
Run Code Online (Sandbox Code Playgroud)

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

forward是类似的,但是重载以返回对右值引用的引用,以及对其他任何内容的左值引用.

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

这或多或少是正确的.官方定义是表达"指定一个函数或一个对象",这些是具有地址的东西.

并且r值专门不是l值

并不是的.稍微简化,表达式可以是左值右值,但可以从一个转换为另一个.的左值可以被隐式转换为右值 ; 转换另一种方式可以使用强制转换来完成move.

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

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

这些新设施是否允许类似的东西 auto x = &(3);

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

auto && rvalue = 3;
auto const & const_lvalue = 3;
Run Code Online (Sandbox Code Playgroud)

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

auto & lvalue = 3;  // ERROR
Run Code Online (Sandbox Code Playgroud)


Jon*_*Mee 5

我不能调用一个函数:void foo(string* bar)像这样:foo(&string("Hello World!"))或者我得到一个错误:

错误:取临时地址

我也不能调用函数:void foo(string& bar)像这样:foo(string("Hello World!"))或者我得到一个错误:

错误:从类型为 'std::string {aka std::basic_string}' 的右值对类型为 'std::string& {aka std::basic_string&}' 的非常量引用无效初始化

C++11 为我提供了做一个右值引用的能力,所以我可以调用一个函数:void foo(string&& bar)像这样:foo(string("Hello World!"));

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

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

    cout << *temp << " @:" << temp << endl;
}
Run Code Online (Sandbox Code Playgroud)

看起来 OP 对右值有很好的控制。但是对它们的这种解释对我很有帮助,可能对其他人也有帮助。它详细介绍了为什么 C++03 允许对右值的常量引用,而不是 C++11 的右值引用。