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

Bar*_*icz 8 c++ c++11

假设我们有一个实用功能:

std::string GetDescription() { return "The description."; }
Run Code Online (Sandbox Code Playgroud)

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

我想总是这样回来:

std::string GetDescription() { return std::move(std::string("The description.")); }
Run Code Online (Sandbox Code Playgroud)

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

std::string GetDescription() { return std::string("The description."); }
Run Code Online (Sandbox Code Playgroud)

然而,我仍然不知道什么是真正做的,而不是什么可以它来做.

Naw*_*waz 13

std::string GetDescription() { return "XYZ"; }
Run Code Online (Sandbox Code Playgroud)

相当于:

std::string GetDescription() { return std::string("XYZ"); }
Run Code Online (Sandbox Code Playgroud)

这相当于这个:

std::string GetDescription() { return std::move(std::string("XYZ")); }
Run Code Online (Sandbox Code Playgroud)

意味着当您返回std::string("XYZ")这是一个临时的对象,则std::move是不必要的,因为对象将移动反正(隐含的).

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


所以这个问题的答案是:

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

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

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

std::string GetDescription() { return "XYZ"; }
Run Code Online (Sandbox Code Playgroud)

在某些角落情况下,return tempObj效率更高(因而更好)return std::move(tempObj).

  • 移动的要求是每当允许复制省略时,C++ 11*要求编译器使用移动构造函数(如果有).然后可以在编译器的选择中省略该移动(就像副本一样).当然,在一个合理的编译器中,它很可能是"临时复制"和"暂时移动"的答案都是"不".名义上它被移动,实际上移动被省略并且返回值是使用文字构造的. (3认同)
  • @Nawaz:嗯,我说"名义上感动"而不是"语义感动".根据移动是否实际被删除(如果移动构造函数具有副作用),某些类的语义是不同的.但我完全同意你的观点,在C++ 11中,如果类型有一个移动构造函数(字符串那么),则不允许复制它.因此,符合elision条件的是移动而不是副本. (3认同)
  • @Nawaz:顺便说一下,`std :: move`抑制省略的原因是,如果没有对临时*进行引用,则允许从临时*中删除.但是`move`确实引用了临时的.因此,在某些情况下,"移动"是一种悲观(如果你将它应用于一个移动成本昂贵的物体,如果你把它放在一边就可以省略).不是说"字符串"移动费用昂贵. (3认同)
  • `move`是不必要的,构造的字符串是临时的. (2认同)