复制省略与结构化绑定一起工作吗 [英] Does copy elision work with structured bindings

查看:29
本文介绍了复制省略与结构化绑定一起工作吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

// 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<>在参数为rvalue时返回x值

引用标准也不错!

推荐答案

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

是的,都是。结构化绑定的要点是为您提供对要绑定到的类型的非结构化元素的命名引用。此:

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取决于我们要析构的类型(数组、类似元组或具有所有公共非静电数据成员的类型)。

强制复制省略适用于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&&

这篇关于复制省略与结构化绑定一起工作吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆