简体   繁体   English

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

[英]C++0x: rvalue reference versus non-const lvalue

When programming in C++03, we can't pass an unnamed temporary T() to a function void foo(T&); 在C ++ 03中编程时,我们无法将未命名的临时T()传递给函数void foo(T&); . The usual solution is to give the temporary a name, and then pass it like: 通常的解决方案是给临时名称,然后传递它:

T v;
foo(v);

Now, along comes C++0x - and now with rvalue references, a function defined as void foo(T&&) will allow me to pass a temporary. 现在,沿着C ++ 0x - 现在使用rvalue引用,定义为void foo(T&&)的函数将允许我传递一个临时值。 Which brings me to my question: since a function that takes an rvalue reference can take both rvalue references (unnamed temporaries) as well as lvalue references (named non-const references), is there any reason to use lvalue references anymore in function parameters? 这让我想到了一个问题:因为一个采用右值引用的函数可以同时使用右值引用(未命名的临时值)以及左值引用(命名为非const引用),是否有理由在函数参数中再使用左值引用? Shouldn't we always use rvalues as function parameters? 我们不应该总是使用rvalues作为函数参数吗?

Granted, a function that takes an lvalue reference would prevent the caller from passing a temporary, but I'm not sure if that's a useful restriction. 当然,一个带左值引用的函数会阻止调用者传递临时值,但我不确定这是否是一个有用的限制。

"since a function that takes an rvalue reference can take both rvalue references (unnamed temporaries) as well as lvalue references (named non-const references)" “因为采用右值引用的函数可以同时使用右值引用(未命名的临时值)以及左值引用(命名为非const引用)”

This is an incorrect statement. 这是一个不正确的陈述。 During the first iterations of the rvalue reference specification this was true, but it no longer is and is implemented at least in MSVC to comply with this later change. 在右值参考规范的第一次迭代期间,这是真的,但它不再是并且至少在MSVC中实现以符合后来的更改。 In other words, this is illegal: 换句话说,这是非法的:

void f(char&&);

char x;
f(x);

In order to call a function expecting rvalue references with an lvalue you must turn it into an rvalue like so: 为了调用一个期望rvalue引用和左值的函数,你必须把它变成一个rvalue,如下所示:

f(std::move(x))

Of course, that syntax makes it quite clear what the difference between a function taking an lvalue reference and one taking an rvalue reference really is: an rvalue reference is not expected to survive the call. 当然,该语法非常清楚地表明采用左值引用的函数与采用右值引用的函数之间的区别是:rvalue引用不会在调用中存活。 This is a big deal. 这是一个大问题。

Now, you can of course make up a new function that does exactly what std::move does and then you "can" use rvalue references sort of like lvalue references. 现在,您当然可以组成一个新函数,它完全执行std :: move所做的操作,然后您“可以”使用rvalue引用类似于左值引用。 I thought about doing this for instance with a visitor framework I have when sometimes you simply don't care about any result of the visitor call, but other times you do and thus need an lvalue reference in those cases. 我考虑过这样做,例如我有一个访问者框架,有时你根本不关心访问者调用的任何结果,但有时你做,因此在这些情况下需要左值引用。 With an rvalue reference I could get both...but it's such a violation of the rvalue reference semantics that I decided it was a bad idea. 使用rvalue引用我可以得到两个......但是它违反了rvalue引用语义,我认为这是一个坏主意。

Your statement may be a confusion based upon this: 您的陈述可能是基于此的混淆:

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

char x;
f(x);

This works, but not because you are passing an lvalue as an rvalue reference. 这可行,但不是因为您将左值作为右值引用传递。 It works because of reference decay (also new in C++0x). 它的工作原理是参考衰减(也是C ++ 0x中的新增功能)。 When you pass an lvalue to such a template it actually gets instantiated like so: 当你将左值传递给这样一个模板时,它实际上是这样实例化的:

void f<char&>(char&&&);

Reference decay says that &&& turns into & so then the actual instantiation looks like this: 参考衰减表示&&&变为&然后实际的实例化如下所示:

void f<char&>(char&);

In other words, you're simply passing an lvalue by reference...nothing new or special about that. 换句话说,你只是通过引用传递一个左值......没什么新的或特别的。

Hope that clears things up. 希望这能说明问题。

It's a useful restriction if that temporary must be actively disposed of, say a pointer to new memory or a limited resource like a file handle. 如果必须主动处理临时值,例如指向new内存的指针或文件句柄等有限资源,则这是一个有用的限制。 But needing to pass those back smells more of "bad design" than it does of "useful restriction." 但需要传递这些背后的气味比“有用的限制”更多的是“糟糕的设计”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将非常量左值引用绑定到右值 - Bind non-const lvalue reference to rvalue 无法将类型的非常量左值引用绑定到类型的右值 - cannot bind non-const lvalue reference of type to an rvalue of type 将右值参数传递给非常量左值引用的参数 - Passing rvalue argument to parameter of non-const lvalue reference 防止非常量左值解析为右值引用而不是const左值引用 - Preventing non-const lvalues from resolving to rvalue reference instead of const lvalue reference 无效转换为C ++ 0x中的非const引用... std :: pair中的错误? - Invalid conversion to non-const reference in C++0x… bug in std::pair? C++0x const RValue 引用为 function 参数 - C++0x const RValue reference as function parameter 在C ++ 03中是否可以使用非常量右值引用? - Is a non-const rvalue reference possible in C++03? 为什么rvalue不能绑定到非const左值引用,除了写入临时值没有效果? - Why can an rvalue not bind to a non-const lvalue reference, other than the fact that writing to a temporary has no effect? 错误:无法将“bool&amp;”类型的非常量左值引用绑定到“bool”类型的右值 - error: cannot bind non-const lvalue reference of type ‘bool&’ to an rvalue of type ‘bool’ 无法将“int&”类型的非常量左值引用绑定到“int”类型的右值 - cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM