来自std::tuple的引用绑定的类型
Type of reference binding from std::tuple
这里的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,而E
是std::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>::type
0表示的类型定义如下:
- 如果
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)
是结构化绑定声明规范中给定的引用类型;
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 运行时错误:引用绑定到类型为"int"的空指针
- 无法将运行时类绑定到 XAML T 必须是 WinRT 类型
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- 结构化绑定初始值设定项表单 { 赋值表达式 } 对于 clang 上的数组类型失败
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 错误:对类型 'const ItemInstance' 的引用无法绑定到类型 'void' 的右值
- 没有类型结构绑定不起作用?
- 为什么"const auto [x, y]"绑定到引用类型时没有按预期运行?
- std::绑定variadic模板和自动返回类型
- 如何对绑定的成员方法进行typedef,然后将该类型用作模板参数
- 在无序映射的结构化绑定中推导类型
- 错误:在类型 "blah blah" 的绑定引用中删除限定符以初始化"some other blah blah"
- 您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)
- 使用 pybind11 绑定 typedef 类型的正确语法是什么?
- C++ 如何将参数绑定到具有相同返回类型的函数,并将它们全部存储在一个容器中
- 为什么按引用传入会导致绑定引用类型错误
- 类型绑定引用中的限定符和 const 类型的初始值设定项中删除