C++ 0x:rvalue引用与非const lvalue

Cha*_*l72 12 c++ lvalue rvalue-reference c++11

在C++ 03中编程时,我们无法将未命名的临时文件T()传递给函数void foo(T&);.通常的解决方案是给临时名称,然后传递它:

T v;
foo(v);
Run Code Online (Sandbox Code Playgroud)

现在,沿着C++ 0x - 现在使用rvalue引用,定义为的函数void foo(T&&)将允许我传递临时值.这让我想到了一个问题:因为一个采用右值引用的函数可以同时使用右值引用(未命名的临时值)以及左值引用(命名为非const引用),是否有理由在函数参数中再使用左值引用?我们不应该总是使用rvalues作为函数参数吗?

当然,一个采用左值引用的函数会阻止调用者传递临时值,但我不确定这是否是一个有用的限制.

Edw*_*nge 19

"因为采用右值引用的函数可以同时使用右值引用(未命名的临时值)以及左值引用(命名为非const引用)"

这是一个不正确的陈述.在右值参考规范的第一次迭代期间,这是真的,但它不再是并且至少在MSVC中实现以符合后来的更改.换句话说,这是非法的:

void f(char&&);

char x;
f(x);
Run Code Online (Sandbox Code Playgroud)

为了调用一个期望rvalue引用和左值的函数,你必须把它变成一个rvalue,如下所示:

f(std::move(x))
Run Code Online (Sandbox Code Playgroud)

当然,该语法非常清楚地表明采用左值引用的函数与采用右值引用的函数之间的区别是:rvalue引用不会在调用中存活.这是一个大问题.

现在,您当然可以组成一个新函数,它完全执行std :: move所做的操作,然后您"可以"使用rvalue引用类似于左值引用.我考虑过这样做,例如我有一个访问者框架,有时你根本不关心访问者调用的任何结果,但有时你做,因此在这些情况下需要左值引用.使用rvalue引用我可以得到两个......但是它违反了rvalue引用语义,我认为这是一个坏主意.

您的陈述可能是基于此的混淆:

template < typename T >
void f(T&&);

char x;
f(x);
Run Code Online (Sandbox Code Playgroud)

这可行,但不是因为您将左值作为右值引用传递.它的工作原理是参考衰减(也是C++ 0x中的新增功能).当你将左值传递给这样一个模板时,它实际上是这样实例化的:

void f<char&>(char&&&);
Run Code Online (Sandbox Code Playgroud)

参考衰变说&&&变成了&那么实际的实例化看起来像这样:

void f<char&>(char&);
Run Code Online (Sandbox Code Playgroud)

换句话说,你只是通过引用传递一个左值......没什么新的或特别的.

希望这能说明问题.