読んだもの2 P0144R1: Structured bindings

稲葉

std::cout << f() << g() << h();
◦ C++14 : f(), g(), h() の評価順序は未規定
◦ 提案 : f(), g(), h() の順で評価

std::map<key_t, size_t> m;
m[key] = m.size();
◦ C++14 : m[key] が 0 になるか 1 になるかは未規定
◦ 提案 : 0 になる

void foo(unique_ptr<T> x, unique_ptr<T> y);
foo(new T, new T);
◦ C++14 : メモリリークするかも
◦ 提案 : しない

などなど、ある程度評価順序を規格で決める

x = x++;
◦ これは変わらず未定義

f( a(), b(), c() );
◦ a(), b(), c() の評価順序は変わらず未規定
◦ ただし、(改造版Visual C++で実験してみた結果)“we feel
confident recommending the left-to-right
evaluation rules” と書いてあるので今後変わるかも

foo().bar().buz() のようなメソッドチェーン
◦ (cf. std::future<>::then)



<< をストリームへの出力演算子として使う
スマートポインタ
などなど、Cに遡る “評価順序は不定” が最初に定義
された頃から比べると、様々なイディオムが発達して
きており、それらのイディオムを自然に活用できるよう
に言語サポートがあるべきだ」


「E << F」 と 「E <<= F」 で順序違うのは…
「E = F」 が右から左で Java や C# と違うのは…
「演算子の結合方向を考えても代入演算だけが右から
左なのは自然」
 「C# チームに何故左から右と定義したのか聞いてみた
ら(C++のように)左辺で頑張りまくることは、そもそもC#
では少ないので…という反応だった」
 Bjarne 「今新しく言語を設計するなら代入は左手の値
が右手に入るようにするんだけどなあ (脱線)」



「*ptr_expr = big_struct_expr;」 で先に左辺でア
ドレスを計算してそこに右辺の結果を直に書き込むと
いう最適化ができなくなる
「逆に右to左だからこそできる最適化も色々あると
GCCの人は言っていた。it depends だ」
See Also: P0217R0: Proposed wording for structured bindings
1.
2.
3.
右辺が配列型なら展開
右辺の型に対して .get<#>() メンバ関数か
get<#>() ADL関数が適用できるなら、それを使っ
て展開
構造体/クラスなら public メンバの先頭から順に
展開

auto のみ (明示的な型宣言やconcept宣言は扱わない)
◦ auto& や const auto は サポート

“Should there be a way to explicitly ignore
variables?”
◦ not yet. std::tie における std::ignore 的な物を用意できたらい
いが、変数宣言部なので簡単ではない

“Should there be support for recursive
destructuring?”
◦ not yet.
◦ 「複雑なことは pattern matching (C++ 2X?) を入れるときにそ
のsyntaxに合わせるように考えたい」

右辺のtupleよりも変数リストが短い場合はエラーにすべ
きでは?
◦  そうする方向に検討が進んでいる模様

提案中のstd::variant にも get<#>があるので“分解”で
きてしまう問題
◦  問題が認識され始めたところ、議論中

auto じゃない型を明示させろ派が大変活発
◦ Bjarne が蹴り続けている
◦ auto {x, y} = std::ensure<int, string>(f()); のようなヘルパー
が書けるからいいだろと言っている人もいる。