#include <string>
std::string f()
{
std::string s;
return std::move(s);
}
int main()
{
f();
}
g++ -Wall z.cpp
给出的警告如下。
z.cpp: In function ‘std::string f()’:
z.cpp:6:21: warning: moving a local object in a return statement prevents copy elision [-Wpessimizing-move]
6 | return std::move(s);
| ~~~~~~~~~^~~
z.cpp:6:21: note: remove ‘std::move’ call
我知道如果我改变 return std::move(s);
到 return s;
,警告将被避免。然而,根据 C++标准, NRVO
,比如说在这种情况下,是不能保证的。如果我写 return s;
我觉得不确定是否 NRVO
将被执行。
如何缓解不确定感?
你应该这样做
std::string f()
{
std::string s;
return s;
}
如果NRVO不适用,则自动完成移动。
参见 return#Automatic_move_from_local_variables_and_parameters(自动从本地变量和参数中移动).
如何避免NRVO的 "悲观化移动 "警告?
只需删除 std::move
. 它在这里没有任何用处,但确实可以防止省略移动。
如果我写了return s;,我就会感到不确定NRVO是否会被执行。
如何缓解这种不确定的感觉?
NRVO是永远无法保证的。你能做的最好的缓解不确定性的方法就是编译,看看这个动作是否被省略了。在实践中,只要启用了优化,我相信任何现代编译器都能完成这个NRVO。
如果你想真正确定避免任何移动,那么返回一个prvalue而不是lvalue。这一点从C++17开始就可以保证被省略。
std::string f()
{
return {};
}