将左值绑定到右值引用移动ctor并返回函数

时间:2011-07-28 20:28:47

标签: c++ c++11 move-semantics

根据我所知,将左值绑定到右值引用是无效的。 其次,左值表达式可以通过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();    
}

我哪里错了?

2 个答案:

答案 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
}

在返回值优化之后发生了所有这些。这意味着在许多情况下,按值返回实际上非常有效。