C++11 以降で move を考慮した場合に関数の引数は値型であるべきか参照型であるべきか
void f(T &&)というシグネチャよりもvoid f(T)の方を推奨する系の言説,f(std::move(x))という式の実行でfが例外を投げた時のxの状態に関する例外安全性について真剣に真摯に考えた深い思索の過程を経ているはずだから,それを文章として添えておいてほしい.
2014-10-13 10:51:44@Cryolite それの何がまずいんですか T && で受けたところで f に制御が移った時点で x の状態は valid but unspecified でしょう
2014-10-13 11:03:20@kikairoya まずいとは一言も言っていないことに注意.右辺値参照で受けるのではなく値型で受ける設計の場合,例えば melpon.org/wandbox/permli… みたいなコードを効率を維持したまま機能させる手段が完全に潰えるのでので,設計の判断の根拠を注記すべきという趣旨.
2014-10-13 11:11:49@kikairoya ごめん,さっきのコード間違えた. melpon.org/wandbox/permli… こっちに訂正.
2014-10-13 11:18:19@kikairoya さっきと同じコードで f が値型を受ける形式に書き換えると melpon.org/wandbox/permli…
2014-10-13 11:22:27@kikairoya つまり,例外が投げられたとき(これは,多くの場合異常系に入ったことを意味する),どういう program state だったのかの事後追跡が(例外に状態を乗せないと)困難になる.
2014-10-13 11:23:59@kikairoya 私は,これは大きな損失だと思うのだが,値型で受けることを主張する人はこの損失よりも template の宣言の数を減らす利益の方が大きいと考えてその設計を選択しているはずだから,その理論的根拠が知りたい,という趣旨の主張.
2014-10-13 11:25:11@Cryolite program state を args だけから推定出来ることは稀(そのような処理、つまりargsをいじくりまわしながら進める処理ならば通常は member function になるだろう)で、それを知りたければ真面目に状態を載せてthrowする以外に無い
2014-10-13 11:27:19@kikairoya 私は非常に弱いとはまったく思っていないのだけれど,いずれにせよ,なのでそういう各々の設計の得失をきちんと明記しておくべきだという主張.
2014-10-13 11:29:24@Cryolite どちらかと言えば例外に状態を載せて伝播させる文化に乏しいことのほうがずっと問題で、啓蒙するならばそっちに注力すべきでは ( .NET や Java の界隈では出来ているんだから C++ でも普及させれば出来るだろう
2014-10-13 11:29:27@kikairoya 特に,値型で受けることを主張する文章では1引数関数テンプレートの例で説明していることが多いので,その組み合わせ爆発の欠点はただちには見えてこない.
2014-10-13 11:29:41@kikairoya 納得した.引数に state を戻すよりも例外にさらに state を move した方が事後にできる処理の選択の幅が広い.
2014-10-13 11:34:28@kikairoya 今はある関数の設計についてだけフォーカスを当てているので,その関数が1引数関数で大域的な状態を参照せず大域的な副作用を及ぼさないなら,当然,引数の state だけが唯一無二の重要な state になる.
2014-10-13 11:39:10@Cryolite ああはい __attribute__((const)) ならそうですね、ところでそれは強い例外安全をあえて破る理由としては不十分だと思う (今思いついた
2014-10-13 11:41:33@kikairoya 今のところ特に思いつかない.例外に状態を乗せた場合と引数に状態を戻した場合の得失についてはちゃんと考えないと良く分からんが前者の場合が多分選択肢の幅は広い.
2014-10-13 11:42:16@kikairoya 「強い例外安全をあえて破る」ってどっちについての言及? 値型で受けるほう? 参照で受けるほう?
2014-10-13 11:43:12@Cryolite 参照で受けて書き換えながら処理すると弱い例外安全になると思う (値で受ければ強い例外安全になる
2014-10-13 11:44:30