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

Why can't I bind a const lvalue reference to a function returning T&&?

我将一个函数的某些 return 值绑定到一个 const 左值引用,但是在 const 左值引用的生命周期结束之前,该对象被删除了。

在下面的示例中,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;
}

输出为:

Foo destroyed: some string
before scope end

靠大肠杆菌生活:1

我以为您可以将 const T& 绑定到任何东西。 return T&& 是不好的做法吗?return 应该按值优先吗?

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

inline utility::string_t&& to_string_t(std::string &&s) { return std::move(s); }

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

非常混乱,因为 to_string_t 的 windows 版本(由预处理器宏调度)return 由值 :

_ASYNCRTIMP utility::string_t __cdecl to_string_t(std::string &&s);

编辑: 为什么将 pass_through 的结果传递给采用 const Foo& 的函数时它会起作用?这种情况下寿命延长了?

来自标准:

15.2 Temporary objects

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.

基本上它的意思是因为你传入了一个临时对象然后没有延长它的生命周期(比如,通过将它移动到左值)所以它的生命周期只会持续到第一个 ; 之后在您的代码中调用 pass_through。在这一点之后,您将留下 foo 作为悬空参考。

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

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

Is returning by rvalue reference more efficient?