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

时间:2012-12-13 10:16:24

标签: c++ c++11

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

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

然而,我不知道 要做什么,而不是可以做什么。

2 个答案:

答案 0 :(得分: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是不必要的,因为该对象将被移动(隐式)。

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


这个问题的答案是:

  

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

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

所以最重要的是:您可以编写此代码并感到高兴:

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

在某些角落案例中,return tempObjreturn std::move(tempObj)更有效(因而更好)。

答案 1 :(得分:1)

  

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

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

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

我会选择:

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

这样显然你返回一个字符串,代码(几乎)是最小的:你依赖于std :: string move-construction。

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