C++ C++;17
我一直避免像下面这样的初始化C++ C++;17,c++,c++17,structured-bindings,C++,C++17,Structured Bindings,我一直避免像下面这样的初始化 const auto& x = a, y = b; const int* const x = ptr_1, *const y = ptr_2; // wot 因为引用和指针限定符不适用于这两种初始化。虽然这是初学者首先学习的东西之一,但与之相关的模糊性让我觉得下面的内容更清晰,读者对它的思考更少 const auto& x = a; const auto& y = b; 有了C++17和结构化绑定,我很高兴看到了很多潜力。C++17禁止
const auto& x = a, y = b;
const int* const x = ptr_1, *const y = ptr_2; // wot
因为引用和指针限定符不适用于这两种初始化。虽然这是初学者首先学习的东西之一,但与之相关的模糊性让我觉得下面的内容更清晰,读者对它的思考更少
const auto& x = a;
const auto& y = b;
有了C++17和结构化绑定,我很高兴看到了很多潜力。C++17禁止了C++14和C++11未能解决的问题,auto x{1}
是一个int
,而不是std::initializer\u list
。但是为什么下面的代码不起作用呢
const auto& [x, y] {a, b};
const auto& [x, y] = {a, b};
后者符合自动推断和初始值设定项列表的新规则,右侧的表达式被视为初始值设定项列表。但对于前一个编译,编译失败,出现以下错误
initializer for variable '[a, b]' with type 'const auto &' contains multiple expressions
是否有任何方法可以使用结构化绑定语法声明x和y,而不必求助于元组、对等?另外,为什么上面的代码示例中前者的代码格式不正确?该语法是否有歧义?此语法不受支持。您只能解压缩已重载的聚合类和对象: 不幸的是,您无法真正使用《酷演绎指南》,因为您希望引用
a
,而不是元组成员。因此,您必须写出模板参数列表
#include <tuple>
int main()
{
int a = 1;
int b = 2;
const auto& [x, y] = std::tuple<int&,int&>{a, b};
}
#包括
int main()
{
INTA=1;
int b=2;
常量auto&[x,y]=std::tuple{a,b};
}
你也不可能像我一样愚蠢,正确地阅读文档
#include <tuple>
int main()
{
int a = 1;
int b = 2;
const auto& [x, y] = std::forward_as_tuple(a, b);
}
#包括
int main()
{
INTA=1;
int b=2;
const auto&[x,y]=std::forward_as_tuple(a,b);
}
const auto&[x,y]=std::tie(a,b)代码>也可以工作。结构化绑定可以说是用于“解包”东西。它不是用来组合普通声明的。该const auto&
既不适用于a
也不适用于b
,尽管外观如此
您的特定尝试违反了:
带有标识符列表的简单声明称为
结构化绑定声明([dcl.struct.bind])。[…]初始值设定项的格式应为“=赋值表达式”
”,格式应为“{assignment expression}
”,或
格式为“(赋值表达式)
”,其中
赋值表达式为数组或非并集类类型
inta=1,b=2;
常数自动位=std::tie(a,b);
这个结构化绑定声明(非常)大致相当于
const auto bitand __e = std::tie(a, b); // hidden variable
auto and x = std::get<0>(__e);
auto and y = std::get<1>(__e);
const auto bitand _e=std::tie(a,b);//隐藏变量
auto和x=std::get(ue);
auto和y=std::get(ue);
(实际使用的是tuple\u元素
,而不是auto
)
注:
常量自动位和
适用于隐藏变量,并且仅适用于隐藏变量x
和y
始终是引用,即使您只编写auto
;它们的引用是否为const
取决于初始值设定项类型的const
传播属性
- 从prvalue初始值设定项物化的临时对象将通过引用绑定延长其生存期
- 在本例中,
x
和y
都属于“对int的引用”类型;写入x=1是有效的代码>
- 在
decltype
措辞中对结构化绑定进行了特殊处理
如果我们谈论的是用两个“reference to int”成员解包一个结构等,那么这些语义就不足为奇了;此类事物上的const
实际上并不影响引用对象的constance。OTOH,如果你想使用结构化绑定声明来完成一些他们不打算做的事情,你会大吃一惊。那const auto&
是可怕的误导。尝试写入x=1代码>@T.C.很有趣。知道为什么这里忽略了const
吗?@HenriMenke这是因为如果你创建一个std::tuple
,然后调用std::get
,那么const
不会传播到指向引用的值。这与常量
应用于指针时的问题相同,指针不传播到实际值,而只传播到指针本身。只能解包结构和元组
完全错误。您还可以(也可以)解压缩任何有std::get()
专门化的内容。原始数组,用户定义的具有奇怪语义的类型,并不重要。@下划线\d这是建议的。我没有读整个提案。我编辑了我的答案以反映您的改进。为什么x
和y
的类型是int&
而不是const int&
?\uu e
的类型是const std::tuple&
,因此对其调用std::get
应该会返回一个常量引用类型,对吗?根据您的示例x
和y
将始终是引用类型,但在这里的示例中,它们并不是特别处理结构绑定的@QUIRITYdecltype
。@QUIRITY当然了,如果你tie
twoconst int
s,你会得到一个tuple
/您是否故意用多图替换了&
和&
?
const auto bitand __e = std::tie(a, b); // hidden variable
auto and x = std::get<0>(__e);
auto and y = std::get<1>(__e);