如果我返回文字而不是声明的 std::string 会发生什么

What happens if I return literal instead of declared std::string?

本文关键字:string std 什么 声明 返回 文字 如果      更新时间:2023-10-16

假设我们有一个实用程序函数:

std::string GetDescription() { return "The description."; }

可以返回字符串文字吗?是否复制了隐式创建的std::string对象?

我想过总是这样返回它:

std::string GetDescription() { return std::move(std::string("The description.")); }

但它当然更长,更冗长。我们也可以假设编译器 RVO 会对我们有所帮助

std::string GetDescription() { return std::string("The description."); }

然而,我仍然不知道它到底做什么,而不是它做什么。

std::string GetDescription() { return "XYZ"; }

相当于这个:

std::string GetDescription() { return std::string("XYZ"); }

这反过来又相当于:

std::string GetDescription() { return std::move(std::string("XYZ")); }

意味着当您返回std::string("XYZ")哪个临时对象时,std::move是不必要的,因为无论如何都会移动该对象(隐式)。

同样,当您返回 "XYZ" 时,显式构造std::string("XYZ")是不必要的,因为构造无论如何都会(隐式)发生。


所以这个问题的答案是:

是否复制了隐式创建的 std::string 对象?

是否。隐式创建的对象毕竟是(隐式)移动的临时对象。但是编译器可以省略这一举动!

所以底线是这样的:你可以写这个代码并感到高兴:

std::string GetDescription() { return "XYZ"; }

在某些极端情况下,return tempObjreturn std::move(tempObj)更有效(因此更好)。

可以返回字符串文字吗?是否复制了隐式创建的 std::string 对象?

还行。你得到的是 std::string 的(隐式)构造函数,创建一个本地副本,然后作为右值引用返回。将客户端代码中的结果转换为字符串,将从右值引用设置该字符串。

如果你使用第二段代码,你就"说得太多了"。代码是正确的,并且它们(几乎)等效(它们应该是等效的,但允许编译器在第一种情况下执行的优化更好*)。

我会选择:

std::string GetDescription() { return std::string("The description."); }
这样,你

返回一个字符串是明确的,并且代码(几乎)是最小的:你依赖于std::string move-construction。

*) 根据@SteveJessop的评论进行了相应编辑。