C++ 为什么结构化绑定依赖于tuple_元素?
结构化绑定方案(C++17功能基于此)的设计需要C++ 为什么结构化绑定依赖于tuple_元素?,c++,c++17,structured-bindings,C++,C++17,Structured Bindings,结构化绑定方案(C++17功能基于此)的设计需要std::tuple_size、成员get或std::get、以及std::tuple_元素。只需要std::tuple\u size和成员get或std::get。据我所知,没有讨论添加这个,它只是出现在最终草案中。考虑到我相信它一般可以实现为 template<std::size_t index, typename T> struct tuple_element { using type = decltype(std::ge
std::tuple_size
、成员get
或std::get
、以及std::tuple_元素
。只需要std::tuple\u size
和成员get
或std::get
。据我所知,没有讨论添加这个,它只是出现在最终草案中。考虑到我相信它一般可以实现为
template<std::size_t index, typename T>
struct tuple_element {
using type = decltype(std::get<index>(std::declval<T>()));
};
模板
结构元组元素{
使用type=decltype(std::get(std::declval());
};
有人知道为什么要添加此要求吗?考虑以下情况:
std::tuple<int, int&>& foo();
auto& [x, y] = foo();
规则的工作原理是,decltype(x)
是x
所指的类型,因此int
。而decltype(y)
是y
所指的类型,因此int&
如果我们通过执行以下操作来避免元组元素:
auto&& x = std::get<0>(__e);
auto&& y = std::get<1>(__e);
出于结构化绑定的目的,我们希望这里的a
和b
的行为方式与那里的x
和y
相同。和a
和b
这里没有引入变量,它们只是\uu e.i
和\uu e.r
的不同名称
在非参考案例中,存在一种我们无法区分的不同场景:
std::tuple<int, int&&> foo();
auto [x, y] = foo();
std::tuple foo();
auto[x,y]=foo();
在此,我们目前通过以下方式打开包装:
auto __e = foo();
std::tuple_element_t<0, decltype(e)>& x = std::get<0>(std::move(__e));
std::tuple_element_t<1, decltype(e)>& y = std::get<1>(std::move(__e));
auto\uu e=foo();
std::tuple_element_t&x=std::get(std::move(u e));
std::tuple_element_t&y=std::get(std::move(u e));
两个std::get
调用都返回int&
,因此您无法使用auto&&
区分它们。。。但是tuple\u element\u t
的结果是不同的-int
和int&
。这种差异也可以在正常的struct情况下看到
†请注意,由于,实际上解包发生在一个唯一命名的变量引用中,绑定中指定的标识符仅引用这些对象。这可能是完美转发所必需的,
std::get
返回std::tuple\u element\u t&
或std::tuple\u element\u t&
您的实现已中断。例如,std::get
返回带有std::tuple
的引用类型,无论元素是否为引用。更糟糕的是,引用取决于std::tuple
的值类别,我认为在您的实现中,它应该是get
而不是std::get
,以使用ADL。实际上,它并没有分解成您所说的内容。它过去是这样的,但是在DR之后它变成了你所说的,但是变量是\uuuuuux
和\uuuuuy
(或其他)和x
和y
指绑定到这些变量的对象。只是为了学究:)为了好奇。我想我会保持答案不变,我想它至少传达了这样一个想法:在你的第一个例子中,@raket1111decltype(x)
也是int&
。@Barry Oh抱歉,我的意思是std::tuple\u element\t&x=std::get(\uu e)
。对于您的示例,\uu e
实际上被转换为get
的x值,因此您可以将int
和int&
与get
的返回类型区分开来,而不是int
和int&
。
std::tuple<int, int&&> foo();
auto [x, y] = foo();
auto __e = foo();
std::tuple_element_t<0, decltype(e)>& x = std::get<0>(std::move(__e));
std::tuple_element_t<1, decltype(e)>& y = std::get<1>(std::move(__e));