左值绑定到右值引用
Posted
技术标签:
【中文标题】左值绑定到右值引用【英文标题】:lvalue binding to rvalue reference 【发布时间】:2013-06-15 18:09:23 【问题描述】:我试图了解左值如何绑定到右值引用。考虑这段代码:
#include <iostream>
template<typename T>
void f(T&& x)
std::cout << x;
void g(int&& x)
std::cout << x;
int main()
int x = 4;
f(x);
g(x);
return 0;
虽然调用 f() 没问题,但调用 g() 会产生编译时错误。这种绑定仅适用于模板吗?为什么?我们可以在没有模板的情况下以某种方式做到这一点吗?
【问题讨论】:
【参考方案1】:由于T
是一个模板参数,T&&
成为一个转发引用。由于引用折叠规则,对于左值,f(T& &&)
变为 f(T&)
,对于右值,f(T &&)
变为 f(T&&)
。
【讨论】:
这是有道理的。但是假设我不需要模板,那么有没有办法获得通用引用,比如上面的例子?为此,我稍微编辑了问题。 @r.v 您可以为左值 (void g(int&)
) 提供第二个重载 g
,或者您可以使用std::move
移动左值。
是的,这些是可能的解决方案,但我希望我们得到一些符合通用参考的东西:给定类型 T(固定,非模板),我可以在一次调用中同时匹配 T& 和 T&& (没有重载),然后使用转发等。这肯定有助于减少一些冗余代码。
@r.v 抱歉,但不包括我建议的内容,如果没有模板,这是不可能的。 :( 顺便说一句,完美转发非常适合模板。
没问题,谢谢。我认为我们在这里有一个合法的用例。【参考方案2】:
0x499602D2 已经回答了您的问题;不过,对您的代码进行以下更改可能会提供进一步的见解。
我在f
中添加了一个static_assert
来检查推导的类型:
#include <type_traits>
template<typename T>
void f(T&& x)
static_assert(std::is_same<T&&, int&>::value,"");
std::cout << x;
断言确实没有失败,所以f
中x
的类型最终是int&
(在这个特定示例中)。
我改变了g
在main
中的调用方式:
g(std::move(x));
现在代码已编译,程序按预期工作并打印44
。
希望这有助于理解右值引用。
【讨论】:
已经有一个模板:std::is_rvalue_reference
以上是关于左值绑定到右值引用的主要内容,如果未能解决你的问题,请参考以下文章
在 C++ 11 中将非 const 左值引用绑定到右值是不是有效?(修改)
error C2662 无法将左值绑定到右值 —— 变量永远是左值,即使它的类型为右值引用
std::forward vs std::move 同时将左值绑定到右值引用