为什么 C++17 结构化绑定不使用 { }?

Why do C++17 structured bindings not use { }?

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

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

但是现在我看到大家都指向

的C++17/C++1z提案语法
auto [a, b] = minmax(data);

现在我学会了 "lists are written { like, this }" 有新的列表语法吗?为什么?这里的花括号有什么问题?

这个还在争论中。考虑到 [] 和 {} 已经有多少用途,很难确定哪种语法最容易混淆。

还有 "least confusing" 和 "easiest to parse" 发生冲突的风险。

从 {} 到 [] 的更改发生在 Jacksonville 会议之后,是为了响应那次会议的评论。这在 p0144r2 中有详细说明:"because it is more visually distinct from the existing syntax for declaring multiple variables of the same type."

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

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

The “structured bindings” proposal originally used braces “{}” to delimit binding identifiers. Those delimiters were changed to brackets “[]” under the assertion that they didn’t introduce any syntactic problem. However, they turned out to introduce syntactic ambiguity with attributes and lambdas. In the light of various suggested fixes, it appears the original syntax is more adequate.

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


更新 从此 trip report:

The original proposal for decomposition declarations used the syntax auto {a, b, c}; that was changed at the last meeting to auto [a, b, c]. This change was fairly controversial, and several comments asked to change it back to {} (while others encouraged keeping the []). There are technical arguments on both sides (the [] syntax can conflict with attributes once you start allowing nested decompositions; the {} syntax can conflict with uniform initialization if you throw Concepts into the mix and allow using a concept-name instead of auto), so in the end it’s largely a matter of taste. The clang implementers did report that they tried both, and found the ambiguities to be easier to work around with []. In the end, there was no consensus for a change, so the status quo ([] syntax) remains.

@SebastianWahl 只评论了 link。 link.

后面的内容我会快速总结一下

Chandler Carruth's answer to this question: 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<int,float,string> {a,b,c} 在 C++ 中也有含义,因此将是一个难以解决的歧义。

方括号语法的一件事是它与 lambda 捕获子句非常相似,其中,同样地,您不指定变量类型,因为 auto 是默示。即

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

这显然不是完全相同的东西,但是当你把它想象成"syntax for auto capturing by making sense of the context,"时,它就可以工作了:

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