来自std::tuple的引用绑定的类型

Type of reference binding from std::tuple

本文关键字:类型 绑定 引用 tuple std 来自      更新时间:2023-10-16

这里的a是什么类型?

#include <iostream>
#include <tuple>
using namespace std;
int main()
{
float x{};
std::tuple<int> tpl( x );
auto& [ a ] = tpl;
static_assert( std::is_same_v< decltype( a ), int> );
//static_assert( std::is_same_v< decltype( a ), int&> );
}

根据标准11.5/3:

[…]给定由CCD_ 2指定的类型Ti,变量引入时具有类型的唯一名称ri"引用Ti">用初始化器初始化(11.6.3),引用所在如果初始值设定项是左值和右值,则为左值引用否则参考。每个vi都是Ti类型的左值的名称指绑定到ri的对象;参考类型是Ti。

这里,对于第一个元素(int),i是0,而Estd::tuple<int>,因此Ti具有类型std::tuple_element<0, std::tuple<int>>::type,即int。此外,ri(在我们的案例中为a)具有类型"对Ti的引用",即左值引用int&,而不仅仅是int。这句话有什么错,为什么编译器clang和gcc都推导出int类型?

变量r0的类型确实是int&。但v0,这里称为a,是另一回事,是结构化绑定的名称,从技术上讲,它根本不是一个变量,只是一种不同的名称。

因此,我们需要在[dcl.type.deltype]中查看decltype的描述:

对于表达式e,由std::tuple_element<i, E>::type0表示的类型定义如下:

  • 如果e是命名结构化绑定的未加括号的id表达式,则decltype(e)是结构化绑定声明规范中给定的引用类型

所以这里的";引用类型";只是CCD_ 23。

当然,正如我们所期望的,decltype((a))就是int&。在没有双括号的名称上使用CCD_;声明";,而不是名称的行为,所以decltype(a)";应该";是这样或那样的,因为a没有正常的声明。尽管给定std::tuple<int, int&> t{0, n}; auto& [a, b] = t;可能有点有用,但我们认为decltype(a)int,而decltype(b)int&

注意

引用的类型为Ti。

对于结构化绑定,decltype产生引用类型([dcl.type.deltype]):

如果e是命名结构化绑定的未加括号的id表达式,则decltype(e)是结构化绑定声明规范中给定的引用类型;

相关文章: