3
#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会被执行。

如何缓解不确定感?

4

2 回答 2

5

你应该做

std::string f()
{
    std::string s;
    return s;
}

如果 NRVO 不适用,移动会自动完成。

请参阅return#Automatic_move_from_local_variables_and_parameters

于 2020-05-28T09:48:55.323 回答
1

如何避免NRVO的“悲观行动”警告?

只需删除std::move. 它在这里没有做任何有用的事情,但确实可以防止忽略移动。

如果我写return s;,我不确定NRVO是否会被执行。

如何缓解不确定感?

NRVO 永远不会得到保证。为了缓解不确定性,你能做的最好的事情就是编译并查看是否省略了移动。在实践中,只要启用优化,我相信任何现代编译器都会执行此 NRVO。

如果您想确定要避免任何移动,请返回纯右值而不是左值。从 C++17 开始,这保证被省略:

std::string f()
{
    return {};
}
于 2020-05-28T09:48:25.687 回答