Rokiのチラ裏

学生による学習のログ

C++17 structured bindings で [ ] が使われる事情

C++17 から導入される structured bindings は、複数の変数をタプルのようなオブジェクトから初期化する事ができる言語機能であるが、同機能における宣言では { } ではなく [ ] が使われる。
そもそも structured bindings の元々の提案では宣言の構文において { } が使われていた*1。しかしそれが後に変更されて*2 [ ] を使うようになったという事実がある。変更の理由としては P0144r2/p3 によると "because it is more visually distinct from the existing syntax for declaring multiple variables of the same type." と述べられており、これと同じ内容を説明する動画もある。この変更には賛否両論あったようで、中には以下のような NB コメントも挙げられた。

  • Nested decomposition declarations can’t work, as they clash with the attribute syntax. --- p0488r0/p4
  • 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. --- p0488r0/p6

また、Botond Ballo 氏の trip report によると[ ]は attribute と競合する可能性があり、また{ }は auto の代わりにコンセプト名を使用できるようにする(!)と、Uniform initialization と競合する可能性があるため、両者に技術的な問題があるとしている。しかし clang の実装者は両方を試した結果、[ ] を利用した方が実装上の曖昧さを回避するのに容易である事を発見したと報告しており、結果的には{ }への変更の合意はなかったため、[ ]を使う構文が残ったという。
個人的には、既存の資産を持つ言語に対して機能を付け加える時、"ユーザーの混乱を最小限に抑える"と"パースを簡単にする"という相互に矛盾したリスクをどのように捉えて設計するかが言語そのものになると私は考えているのだが、その点においてこの仕様は、良くも悪くも何となく C++ らしいなと思った。