c++ - 返回 std::tuple 并 move 语义/复制省略

标签 c++ c++17 move-semantics

我有以下工厂函数:

auto factory() -> std::tuple<bool, std::vector<int>>
{
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);

    return { true, vec };
}

auto [b, vec] = factory();

在 return 语句中 vec 是否被视为 xvalueprvalue 并因此被 move 或复制省略?

我的猜测是否定的,因为编译器在 return 语句中对 std::tuple 进行列表初始化时,仍然不知道 vec 将被销毁。所以可能需要一个明确的 std::move :

auto factory() -> std::tuple<bool, std::vector<int>>
{
    ...
    return { true, std::move(vec) };
}

auto [b, vec] = factory();

真的需要吗?

最佳答案

In the return statement is vec considered an xvalue or prvalue and therefore moved or copy elided?

vec 始终 是一个左值。即使在简单的情况下:

std::vector<int> factory() {
    std::vector<int> vec;
    return vec;
}

那是仍然返回一个左值。只是我们有 special rules也就是说,在这种情况下,当我们返回一个自动对象的名称时,我们只是忽略了拷贝(在复制省略不适用的情况下,还有另一个 special rule,但我们仍然尝试从左值 move )。

但那些特殊规则适用于return object; 情况,它们不适用于return {1, object}; 案例,无论它看起来多么相似。在您的代码中,这将复制一份,因为这就是您所要求的。如果你想做一个 Action ,你必须做:

return {1, std::move(object)};

为了避免 move ,您必须:

auto factory() -> std::tuple<bool, std::vector<int>>
{
    std::tuple<bool, std::vector<int>> t;

    auto& [b, vec] = t;
    b = true;
    vec.push_back(1);
    vec.push_back(2);
    return t;
}

关于c++ - 返回 std::tuple 并 move 语义/复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64541229/

相关文章:

c++ - 将 C++ dll 注入(inject)器转换为 unicode

c++ - 第 924 行 : Char 9: runtime error: reference binding to null pointer of type 'int' (STL_vector. h)

c++ - nvcc/cuda 3.1 - ghtr-default.h 泛滥 "declared static"但未定义警告

c++ - std::visit和std::variant用法

c++ - 不匹配 ‘operator=’

c++ - 我可以将 move 的变量标记为不再可用,并在使用它时收到编译器警告吗?

c++ - Cmake 中的 Boost 文件系统版本错误

c++ - 如何使特征接受参数包?

c++ - static/dynamic/const/reinterpret_cast 可以在未评估的上下文中使用吗?

c++ - qsort 不适用于 C++ 中的哪些类型?