复制省略与结构化绑定一起工作吗

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

// 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>
然后,由于__E是not 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&&

相关文章