繁体   English   中英

C++17 中的初始化列表和结构化绑定推导歧义

[英]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适用于隐藏变量且仅适用于隐藏变量。 即使你只写autoxy也总是引用; 它们的引用对象是否为const取决于初始化器类型的const传播属性。
  • 从纯右值初始化器物化的临时对象将通过引用绑定延长其生命周期。
  • 在这个例子中, xy都是“对 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM