8

假设我们有一个效用函数:

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."); }

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

4

2 回答 2

13
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是不必要的,因为该对象无论如何都会被移动(隐式)。

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


所以这个问题的答案:

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

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

所以底线是这样的:您可以编写这段代码并感到高兴:

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

在某些极端情况下,return tempObjreturn std::move(tempObj).

于 2012-12-13T10:21:11.993 回答
1

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

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

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

我会去:

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

这样,您返回一个字符串是明确的,并且代码(几乎)是最少的:您依赖于 std::string 移动构造。

*) 在@SteveJessop 发表评论后进行了相应编辑。

于 2012-12-13T10:28:37.293 回答