为什么我不能将const左值引用绑定到返回T &&的函数?

Mar*_*kus 8 c++ move-semantics c++11

我将函数的某些返回值绑定到const左值引用,但是在const lvalue引用的生命周期结束之前删除了该对象.

在以下示例中,Foo对象在foo结束的生命周期之前被销毁:

#include <iostream>
#include <string>

struct Foo
{
    ~Foo()
    {
        std::cout << "Foo destroyed: " << name << std::endl;
    }
    std::string name;
};

Foo&& pass_through(Foo&& foo)
{
    return std::move(foo);
}

int main()
{
    const Foo& foo = pass_through({"some string"});
    std::cout << "before scope end" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Foo被破坏:
范围结束前的一些字符串

住在coliru:1

我以为你可以绑定const T&任何东西.返回是不好的做法T&&,应该按价值返回?

我在这里的cpprestsdk偶然发现了这个:

inline utility::string_t&& to_string_t(std::string &&s) { return std::move(s); }
Run Code Online (Sandbox Code Playgroud)

https://github.com/Microsoft/cpprestsdk/blob/master/Release/include/cpprest/asyncrt_utils.h#L109

非常混乱,因为Windows版本to_string_t(由预处理器宏调度)返回值:

_ASYNCRTIMP utility::string_t __cdecl to_string_t(std::string &&s);
Run Code Online (Sandbox Code Playgroud)

编辑:为什么在将结果传递pass_through给函数时它可以工作const Foo&?在这种情况下,寿命延长了吗?

Fib*_*les 4

从标准来看:

15.2 临时对象

6.9 A temporary object bound to a reference parameter in a function call persists 
    until the completion of the full-expression containing the call.
Run Code Online (Sandbox Code Playgroud)

本质上它的意思是,因为您传入了一个临时对象,然后没有延长其生命周期(例如,通过将其移至左值),所以它的生命周期仅持续到代码中;调用后的第一个。pass_through在此之后,您将留下foo一个悬而未决的参考。

int main()
{
    const Foo& foo = pass_through({"some string"}); // "some string" lifetime ends here
    std::cout << "before scope end" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

至于返回右值引用是否是一种好的做法,我相信这两个答案已经详细介绍了该主题:

我应该通过右值引用返回右值引用参数吗?

通过右值引用返回是否更有效?