c++ - 复制省略是否适用于结构化绑定(bind)

标签 c++ c++17 rvalue copy-elision structured-bindings

强制复制省略是否适用于通过结构化绑定(bind)进行的分解?这适用于以下哪些情况?

// one
auto [one, two] = std::array<SomeClass>{SomeClass{1}, SomeClass{2}};

// two
auto [one, two] = std::make_tuple(SomeClass{1}, SomeClass{2});

// three
struct Something { SomeClass one, two; };
auto [one, two] = Something{};    

我怀疑只有第三种情况允许复制省略,因为前两种情况将通过 std::get<>“分解”和 std::tuple_size<>std::get<>当参数是右值时返回 xvalues

引用标准也很好!

最佳答案

Does mandatory copy elision apply to decomposition via structured bindings? Which of the following cases does that apply to?

是的,所有这些。结构化绑定(bind)的重点是为您提供对您要绑定(bind)的类型的解构元素的命名引用。这个:

auto [one, two] = expr;

只是语法糖:

auto __tmp = expr;
some_type<0,E>& a = some_getter<0>(__tmp);
some_type<1,E>& b = some_getter<1>(__tmp);

在哪里 some_typesome_getter取决于我们要解构的类型(数组、类元组或具有所有公共(public)非静态数据成员的类型)。

强制复制省略适用于 auto __tmp = expr行,其他行均不涉及拷贝。


评论中的示例有些困惑,所以让我详细说明一下:

auto [one, two] = std::make_tuple(Something{}, Something{});

那个 expands into :

auto __tmp = std::make_tuple(Something{}, Something{}); // note that it is from
// std::make_tuple() itself that we get the two default constructor calls as well
// as the two copies.
using __E = std::remove_reference_t<decltype(__tmp)>; // std::tuple<Something, Something>

那么,由于 __Enot an array type但是 is tuple-like ,我们通过 unqualified call to get looked up in the associated namespace of __E 引入变量.初始化程序将是 xvalue类型为 rvalue references :

std::tuple_element_t<0, __E>&& one = get<0>(std::move(__tmp));
std::tuple_element_t<1, __E>&& two = get<1>(std::move(__tmp));

请注意,虽然 onetwo都是对 __tmp 的右值引用, decltype(one)decltype(two)both yield Something 而不是 Something&& .

关于c++ - 复制省略是否适用于结构化绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45698326/

相关文章:

c++ - 我如何构建一个从 git fork 克隆的单独的 boost 库?

c++ - 无法将字段 'pair' 声明为抽象类型 'System'

c++ - 调用指向成员函数的数组元素

c++ - 标准库中是否存在类型级别的左折叠元功能?

c++ - 在几层继承上重载解析?

c++ - 为什么它需要一个右值复制构造函数,即使它不会被调用?

c++ - R 和 L 值是否与其上下文有关?

c++ - 分配给右值 : why does this compile?

c++ - 翻译后顶点缓冲区中的数据会改变吗?

c++ - 除了 std::string_view 方法之外, std::string_view 比 char* 有什么优势吗?