C++11 以降で move を考慮した場合に関数の引数は値型であるべきか参照型であるべきか

void f(T); 対 void f(T const &); 続きを読む
10
Akso de la Malbono @Cryolite

void f(T &&)というシグネチャよりもvoid f(T)の方を推奨する系の言説,f(std::move(x))という式の実行でfが例外を投げた時のxの状態に関する例外安全性について真剣に真摯に考えた深い思索の過程を経ているはずだから,それを文章として添えておいてほしい.

2014-10-13 10:51:44
若年寄(もう若くない) @kikairoya

@Cryolite それの何がまずいんですか T && で受けたところで f に制御が移った時点で x の状態は valid but unspecified でしょう

2014-10-13 11:03:20
Akso de la Malbono @Cryolite

@kikairoya まずいとは一言も言っていないことに注意.右辺値参照で受けるのではなく値型で受ける設計の場合,例えば melpon.org/wandbox/permli… みたいなコードを効率を維持したまま機能させる手段が完全に潰えるのでので,設計の判断の根拠を注記すべきという趣旨.

2014-10-13 11:11:49
若年寄(もう若くない) @kikairoya

@Cryolite それのどこがどうおいしいのかよくわからない

2014-10-13 11:13:57
Akso de la Malbono @Cryolite

@kikairoya ごめん,さっきのコード間違えた. melpon.org/wandbox/permli… こっちに訂正.

2014-10-13 11:18:19
Akso de la Malbono @Cryolite

@kikairoya さっきと同じコードで f が値型を受ける形式に書き換えると melpon.org/wandbox/permli…

2014-10-13 11:22:27
若年寄(もう若くない) @kikairoya

@Cryolite え、うん、それで、結局何が言いたいのかやっぱりわからない

2014-10-13 11:23:50
Akso de la Malbono @Cryolite

@kikairoya つまり,例外が投げられたとき(これは,多くの場合異常系に入ったことを意味する),どういう program state だったのかの事後追跡が(例外に状態を乗せないと)困難になる.

2014-10-13 11:23:59
Akso de la Malbono @Cryolite

@kikairoya 私は,これは大きな損失だと思うのだが,値型で受けることを主張する人はこの損失よりも template の宣言の数を減らす利益の方が大きいと考えてその設計を選択しているはずだから,その理論的根拠が知りたい,という趣旨の主張.

2014-10-13 11:25:11
若年寄(もう若くない) @kikairoya

@Cryolite それは T && と const T && の組み合わせ爆発を甘受する理由としては非常に弱い

2014-10-13 11:25:33
若年寄(もう若くない) @kikairoya

@Cryolite program state を args だけから推定出来ることは稀(そのような処理、つまりargsをいじくりまわしながら進める処理ならば通常は member function になるだろう)で、それを知りたければ真面目に状態を載せてthrowする以外に無い

2014-10-13 11:27:19
Akso de la Malbono @Cryolite

@kikairoya 私は非常に弱いとはまったく思っていないのだけれど,いずれにせよ,なのでそういう各々の設計の得失をきちんと明記しておくべきだという主張.

2014-10-13 11:29:24
若年寄(もう若くない) @kikairoya

@Cryolite どちらかと言えば例外に状態を載せて伝播させる文化に乏しいことのほうがずっと問題で、啓蒙するならばそっちに注力すべきでは ( .NET や Java の界隈では出来ているんだから C++ でも普及させれば出来るだろう

2014-10-13 11:29:27
Akso de la Malbono @Cryolite

@kikairoya 特に,値型で受けることを主張する文章では1引数関数テンプレートの例で説明していることが多いので,その組み合わせ爆発の欠点はただちには見えてこない.

2014-10-13 11:29:41
若年寄(もう若くない) @kikairoya

@Cryolite 1引数関数で引数から内部状態を推測できる有効な実例の例示を要求する

2014-10-13 11:30:57
若年寄(もう若くない) @kikairoya

@Cryolite それが例外に状態を載せられない理由も含めて。

2014-10-13 11:31:18
若年寄(もう若くない) @kikairoya

あたまいたくてぐったりしてるんだから頭使わせんでくれ(言いがかり

2014-10-13 11:32:00
Akso de la Malbono @Cryolite

@kikairoya 納得した.引数に state を戻すよりも例外にさらに state を move した方が事後にできる処理の選択の幅が広い.

2014-10-13 11:34:28
Akso de la Malbono @Cryolite

@kikairoya 今はある関数の設計についてだけフォーカスを当てているので,その関数が1引数関数で大域的な状態を参照せず大域的な副作用を及ぼさないなら,当然,引数の state だけが唯一無二の重要な state になる.

2014-10-13 11:39:10
若年寄(もう若くない) @kikairoya

@Cryolite ああはい __attribute__((const)) ならそうですね、ところでそれは強い例外安全をあえて破る理由としては不十分だと思う (今思いついた

2014-10-13 11:41:33
Akso de la Malbono @Cryolite

@kikairoya 今のところ特に思いつかない.例外に状態を乗せた場合と引数に状態を戻した場合の得失についてはちゃんと考えないと良く分からんが前者の場合が多分選択肢の幅は広い.

2014-10-13 11:42:16
Akso de la Malbono @Cryolite

@kikairoya 「強い例外安全をあえて破る」ってどっちについての言及? 値型で受けるほう? 参照で受けるほう?

2014-10-13 11:43:12
若年寄(もう若くない) @kikairoya

@Cryolite まあ一応 -fno-exceptions というのがあることはあるけど。。。

2014-10-13 11:43:14
若年寄(もう若くない) @kikairoya

@Cryolite 参照で受けて書き換えながら処理すると弱い例外安全になると思う (値で受ければ強い例外安全になる

2014-10-13 11:44:30