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

时间:2018-12-31 10:55:07

标签: c++ c++17 structured-bindings

undefined的类型是什么?

a

根据标准11.5 / 3:

  

[...]给定#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&> ); } 指定的Ti类型,   变量以唯一类型ri引入,类型为   Ti” 使用初始化程序(11.6.3)初始化,其中引用为   如果初始化程序是左值和右值,则为左值引用   否则参考。每个vi是Ti类型的左值的名称,   指绑定到ri的对象;引用的类型是Ti。

此处,第一个元素(int)的std::tuple_element<i, E>::type为0,而iE,因此std::tuple<int>的类型为Ti,即{{1 }}。另外std::tuple_element<0, std::tuple<int>>::type(在我们的情况下为int)具有“对Ti的引用”类型,即左值引用ri,而不仅仅是a。 该报价中有什么问题?为什么int&类型由clang和gcc编译器推导出来?

2 个答案:

答案 0 :(得分:3)

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

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

  

对于表达式e,由decltype(e)表示的类型定义如下:

     
      
  • 如果e是未命名的 id-expression 命名结构化绑定,则decltype(e)是结构化绑定声明的规范中给出的引用类型;
  •   

因此,这里的“引用类型”仅为int

当然,decltype((a))int&,正如我们期望的那样。不带双括号的名称上的decltype用于查找名称的“声明”方式,而不是名称的行为方式,因此decltype(a)“应该”是一件事还是另一件事并不明显,因为a没有普通的声明。尽管给定std::tuple<int, int&> t{0, n}; auto& [a, b] = t;可能有点有用,但我们有decltype(a)intdecltype(b)int&

答案 1 :(得分:1)

注意

  

引用的类型是Ti。

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

  

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