以下 std::move 情况是多余的吗?

Joã*_*res 2 c++ move

下面的情况是std::move多余的吗?

std::string member;

obj(std::initializer_list<std::string> p_list)
    : member {std::move(join(p_list))}
{}
Run Code Online (Sandbox Code Playgroud)

这是连接函数:

std::string join(string_initializer_list p_list) {
    size_t size {};
    for (auto const & s : p_list) {
        size += s.size();
    }
    std::string output;
    output.reserve(size);
    for (auto const & s : p_list) {
        output.append(s);
    }
    return output;
}
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 5

不,你不需要std::move。的功能std::move是将任何值转换为右值。您的函数已经返回了一个右值,因此就将结果绑定到引用而言,转换没有任何影响(这是您member从右值初始化所追求的)。

实际上,使用std::move主动抑制复制省略,所以是严格的悲观化:

std::string s = join({});             // construct from prvalue, elidable,
                                      // elision mandatory in C++17

std::string s = std::move(join({}));  // temporary object must be constructed,
                                      // s is initialized by moving from the
                                      // temporary
Run Code Online (Sandbox Code Playgroud)

在第一种形式中std::string s = join({});,复制省略意味着join直接构造返回的对象代替s(不构造临时对象,进行复制或移动),而且output函数体中的变量也被省略并直接构造在返回值,即在s. 使用 时std::move,第一个省略步骤不可用。