如何避免 NRVO 的 "pessimizing-move" 警告?

How to avoid the "pessimizing-move" warning of NRVO?

#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++ standardNRVO,这种情况下的说法,是不能保证的。如果我写return s;,我不确定NRVO是否会被执行

如何缓解不确定感?

How to avoid the "pessimizing-move" warning of NRVO?

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

If I write return s;, I feel uncertain whether NRVO will be executed.

How to ease the feel of uncertainty?

NRVO 永远无法保证。为减轻不确定性,您能做的最好的事情就是编译并查看移动是否被省略。实际上,只要启用优化,我相信任何现代编译器都能执行此 NRVO。

如果您想真正确定避免任何移动,那么 return 一个纯右值而不是一个左值。这保证从 C++17 开始被省略:

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

你应该做

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

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

参见return#Automatic_move_from_local_variables_and_parameters