作为函数参数的引用元组

Ale*_*sky 2 c++ temporary-objects c++20

我不太明白为什么func下面代码中的第二次调用不起作用:

\n
#include <string>\n#include <iostream>\n#include <tuple>\n\nusing Tuple = std::tuple<const int&, const std::string&>;\n\nvoid func(const Tuple& t)\n{\n    std::cout << std::get<1u>(t) << std::endl;\n}\n\nint main()\n{\n    const int n = 3;\n    const std::string text = "xyz";\n    \n    func(Tuple(n, text));\n\n    //Does not work:\n    //func(Tuple(5, "abc"));\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

临时字符串什么时候"abc"销毁?

\n

编辑1

\n

所以,最后,根据 \xe5\xba\xb7\xe6\xa1\x93\xe7\x91\x8b 这是有效的:

\n
    func(Tuple(5, std::string("abc")));\n
Run Code Online (Sandbox Code Playgroud)\n

但这并没有:

\n
    Tuple t(5, std::string("abc"));\n    func(t);\n
Run Code Online (Sandbox Code Playgroud)\n

正确的?如果是的话有什么区别?

\n

康桓瑋*_*康桓瑋 11

您的第二种情况正是标准想要检测和禁止的情况。

\n

由于"abc"不是类型std::string引用P2255 :

\n
\n
std::tuple<const std::string&> t("meow");\n
Run Code Online (Sandbox Code Playgroud)\n
\n

此构造总是创建悬空引用,因为临时引用是在选定的( )std::string构造函数内部创建的,而不是在外部创建的。因此,与从右值隐式转换 \xe2\x80\x99s不同,这种构造在任何情况下都不可能是正确的。tupletemplate<class... UTypes> tuple(UTypes&&...)string_viewstring

\n
\n
\n

由于P2255的存在,C++23 中的格式Tuple(5, "abc")不再良好

\n

为了防止临时字符串被破坏,您可以显式指定类型,std::string例如func(Tuple(5, std::string("abc"))).

\n