根据我所知,将左值绑定到右值引用是无效的。 其次,左值表达式可以通过adress-of运算符(&)
的前缀来识别。如果这两句话与以下代码相符,我有点麻烦:
#include<iostream>
struct Foo
{
Foo(Foo&& other)
{
std::cout << "move ctor called";
}
Foo(const Foo& other)
{
std::cout << "copy ctor called";
}
Foo(){}
};
Foo return_foo()
{
Foo f;
return f;
}
void main()
{
Foo f = return_foo(); // Move ctor is called, but return_foo() is a lvalue ??
std::cin.ignore();
}
我哪里错了?
答案 0 :(得分:4)
return_foo()
返回一个prvalue(因为它返回未命名的临时对象)。引自§3.10/ 1,强调我的:
prvalue(“纯”rvalue)是一个不是xvalue的rvalue。 [ 示例:调用返回类型不是a的函数的结果 引用是一个prvalue。一个文字的值,如12,7.3e5或 true也是一个prvalue。 - 例子]
答案 1 :(得分:2)
有一个特殊规则允许将临时值作为右值返回,即以下是等价的 - 明确的“我不再需要它”版本:
T foo()
{
T t(a, b, ...); // constructed somehow
/* ... */
return std::move(t);
}
int main()
{
T t = foo(); // we can move-construct this
}
...和隐式版本:
T foo()
{
T t(a, b, ...);
/* ... */
return t; // implicitly allow moving
}
在返回值优化之后发生了所有这些。这意味着在许多情况下,按值返回实际上非常有效。