我一直避免像以下
这样的初始化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_list<int>
。但为什么以下代码不起作用?
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,而不必求助于元组,对等等?另外为什么上面的代码示例中的前者形成了错误的代码?这种语法有歧义吗?
答案 0 :(得分:3)
结构化绑定可以说是“拆包”的东西。它不是一种组合正常声明的方法。 const auto&
适用于a
和b
,尽管有外观。
您的特定举动违反了[dcl.dcl]/8:
带有标识符列表的简单声明称为a 结构化绑定声明([dcl.struct.bind])。 [...] 初始值设定项的格式为“
= assignment-expression
”,格式为“{ assignment-expression }
”,或者 形式为“( assignment-expression )
”,其中 assignment-expression 是数组或非联合类类型。
int a = 1, b = 2;
const auto bitand <:x, y:> = 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);
(真实的是使用tuple_element
,而不是auto
。)
注意:
const auto bitand
适用于隐藏变量,仅适用于隐藏变量。即使您只写x
,y
和auto
也始终是引用;它们的引用是否为const
取决于初始化程序类型的const
传播属性。x
和y
都是“int to int”类型;写x = 1;
。decltype
措辞中的结构化绑定进行了特殊处理。如果我们讨论用两个“引用int”成员来解压缩结构等,这些语义就不足为奇了;关于这些事情的const
实际上并不影响指示物的常数。 OTOH,如果你想使用结构化绑定声明来解决他们不想做的事情,你会感到非常惊讶。
答案 1 :(得分:0)
此语法不受支持。您只能解压缩public sealed class GlobalInfo
{
private static readonly GlobalInfo _instance;
public int Orden { get; set; }
private GlobalInfo() { }
public static GlobalInfo Instance
{
get
{
if (_instance == null)
{
_instance = new GlobalInfo();
}
return _instance;
}
}
}
已超载的聚合类和对象:https://skebanga.github.io/structured-bindings/
不幸的是,您无法真正使用酷演绎指南,因为您需要引用std::get
而不是元组成员。因此,您必须写出模板参数列表。
a
你也可能不像我一样愚蠢,并正确阅读文档。
#include <tuple>
int main()
{
int a = 1;
int b = 2;
const auto& [x, y] = std::tuple<int&,int&>{a, b};
}
#include <tuple>
int main()
{
int a = 1;
int b = 2;
const auto& [x, y] = std::forward_as_tuple(a, b);
}
也适用。