【问题标题】:Why do C++17 structured bindings not use { }?为什么 C++17 结构化绑定不使用 {}?
【发布时间】:2016-10-30 19:57:00
【问题描述】:

我找到了*C++ 结构化绑定here 的原始提案。它提出了一种轻松绑定多个返回值的方法,即:

auto {a, b} = minmax(data);

但是现在看到大家都指向了C++17/C++1z的提案语法

auto [a, b] = minmax(data);

既然我学会了“列表是写成 { 就像,这个 }”,那么有一个新的列表语法吗?为什么?这里的大括号有什么问题?

【问题讨论】:

  • 通常这种古怪的变化与简化解析器的工作有关。
  • 大括号的一个问题是大括号直到现在才划定范围,而在这里他们不会。相比之下,您可以将方括号想象成 lambda 捕获列表中的样子,并且效果相当不错。
  • 注意:目前还没有 C++17。 C++17 仍在开发中。至少要到 2 月才能确定其中会出现什么,不会出现什么,以及以何种形式出现。
  • 我们确实有一些 NB cmets 请求{},所以我们会看到...
  • Chandler Carruth 对这个问题的回答:youtu.be/430o2HMODj4?t=15m50s

标签: c++ c++17 structured-bindings


【解决方案1】:

这仍在辩论中。鉴于 [] 和 {} 已经有多少用途,很难确定哪种语法最容易混淆。

“最不容易混淆”和“最容易解析”也存在冲突的风险。

【讨论】:

  • 对不起,小姐,这是您的数组大小中的 constexpr lambda,还是结构化绑定上的属性?
  • 可能是早期的 clang++ 实现已经把我们搞砸了。
【解决方案2】:

西班牙和美国的国家机构已提议改回 {} 语法,因为 (P0488R0):

最初使用的“结构化绑定”提案 大括号“{}”分隔绑定标识符。那些 分隔符更改为括号“[]” 断言他们没有引入任何句法 问题。然而,他们竟然介绍了 属性和 lambda 的语法歧义。在 鉴于各种建议的修复,似乎 原始语法更合适。

因此,仍有可能最终获得 C++17 的原始语法(我坚信这是大多数用户的首选)。


更新来自这个trip report

分解声明的原始提案使用语法auto {a, b, c};,在上次会议上更改为auto [a, b, c]。此更改颇具争议,一些 cmets 要求将其更改回{}(而其他人则鼓励保留[])。双方都有技术论据(一旦您开始允许嵌套分解,[] 语法可能与属性冲突;如果您将概念混入其中并允许使用概念名称而不是auto),所以最终这在很大程度上取决于口味。 clang 实现者确实报告说他们都尝试了这两种方法,并发现使用[] 更容易解决歧义。最后,没有就改变达成共识,所以保持现状([] 语法)。

【讨论】:

  • 虽然我既不同意也不反对将分隔符改回原始语法的愿望,但我确实觉得有趣的是,其中一个 NB 将更改描述为突然或最后一分钟,当时它是几个修订前。
  • @MikelF 除了 ES 和 US,还有来自 GB 的相关评论:“嵌套分解声明不起作用,因为它们与属性语法冲突”
【解决方案3】:

@SebastianWahl 只评论了一个链接。我会快速总结链接背后的内容。

Chandler Carruth 对这个问题的回答:youtu.be/430o2HMODj4?t=15m50s

auto [a,b,c] = f();

auto 没问题。但你也可以这样做:

tuple<int,float,string> [a,b,c] = f();

所以当你使用{...} 时,这会变成

tuple<int,float,string> {a,b,c} = f();  //<<< not C++17

这是不好的,因为tuple&lt;int,float,string&gt; {a,b,c} 在 C++ 中也有含义,因此将是一个难以模棱两可,难以解决的问题。

【讨论】:

    【解决方案4】:

    从 {} 更改为 [] 发生在杰克逊维尔之后,是为了响应该会议的 cmets。这在p0144r2 中有详细说明,其中指出:“因为它在视觉上与声明多个相同类型的变量的现有语法更加不同。”

    在 2016 年 11 月的会议上,要求更改 {} 的原始用法的 NB cmets 似乎没有增加共识,使 [] 的用法保持不变。至少在春季会议之前。

    【讨论】:

    • 真的吗?天啊。是吗?
    • @towi 这是非常主观的陈述之一。我找不到任何包含在杰克逊维尔会议上提出更改的会议记录的文件,所以我只能推测。
    • 什么是NB?和NB cmets?
    • NB 代表国家机构。
    【解决方案5】:

    对于方括号语法要说的一点是,它非常类似于 lambda 捕获子句,同样,您无需指定变量类型,因为隐含了 auto。即

    auto func = [a, b] {}
    auto func = [a=1, b=2.0] {}
    

    这显然不是一回事,但是当您将其视为“通过理解上下文进行自动捕获的语法”时,它可以工作:

    auto [a, b] = std::make_pair(1, 2.0);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-27
      • 2018-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      相关资源
      最近更新 更多