[英]C++17 class template argument deduction not working in initializer list, why?
[英]Initializer list and structured bindings deduction ambiguity in 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_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 而不必求助于元组、对等? 另外为什么上面的代码示例中的前者是格式错误的代码? 那个语法有歧义吗?
可以说,结构化绑定用于“解包”事物。 它不是为了结合普通声明而设计的。 尽管外观如此, const auto&
既不适用于a
也不适用于b
。
您的特定尝试违反了[dcl.dcl]/8 :
带有标识符列表的简单声明称为结构化绑定声明([dcl.struct.bind])。 [...]初始值设定项的形式应为“
= 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
适用于隐藏变量且仅适用于隐藏变量。 即使你只写auto
, x
和y
也总是引用; 它们的引用对象是否为const
取决于初始化器类型的const
传播属性。x
和y
都是“对 int 的引用”类型; 写x = 1;
是有效的x = 1;
.decltype
措辞中有对结构化绑定的特殊处理。 如果我们正在谈论使用两个“对 int 的引用”成员解压缩结构等,这些语义就不足为奇了; 此类事物上的const
实际上并不影响所指对象的const
。 OTOH,如果您想将结构化绑定声明用于它们并非旨在做的事情,那么您会感到意外。
只是不支持此语法。 您只能解包std::get
已重载的聚合类和对象: https : //skebanga.github.io/structured-bindings/
不幸的是,您不能真正使用很酷的推导指南,因为您想要引用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);
}
const auto& [x, y] = std::tie(a, b);
也有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.