http://woofertime.com/woof/3024


うーん、decltypeややこしい… eが識別子として、"type of e"と言ったとき、「識別子を宣言したときに書いた型」と捉えるのと、「式を評価した結果の型」と捉えるのでは期待する結果(型推論のルール)が違うからなぁ。それをdecltype一本でやろうとすると、書いてある式によって推論規則を変えるしかないわけで、まぁそうなりますよねという。規格の文面で読めばすごいはっきりしてるんだけど、その規格に従うとdecltype(e)とdecltype((e))で型が変わるとかってどうも無理してるような感じがする。いっそのことBoost.Typeofみたいな仕様(式の型が何であれ参照は外す)とか、単純にsizeof(e)で取得できるサイズの対象となる型を返すとかなら多分直感的だと思う。で、そうじゃない規則で型推論してほしい場合は、例えばidentity_type(e)とか、 result_of(f(1, 2))とか、そういうのを用意しておいたらいいんじゃないかなぁ…また余計な機能が増やすのかとか怒られそうだけど。それにしてもdecltypeの推論規則はかなりうまいと思う。ところでdecltypeにラムダ式を書けないというのは、decltype({return 1;}())っていう形式なら書かせろよとか思うのですが、どうなんですかね?ていうか書けないんですかこれ?これならラムダ式に付けられる(であろう内部的な)型は関係なくて、その戻り値の型だから問題ないでしょって思ったけど、どうなんですか?できてもうれしい場面って思いつかないんだけど、こういう機能は月の人達なら思いもよらない使い方を見つけたりするから、あってもいいと思う。あと、括弧のあるなしで型が変わってくるっていうのは、多分プリプロセッサとの相性が抜群に悪いと思…ったんだけど、そうでもないかなぁ。FOO(e), FOO)((e))(, FOO(f())…あぁ、id-expression以外では括弧のあるなしによる結果の差異はないか。よかった。あ、ラムダ式をdecltypeに書けないことで思いだしたけど、auto f = {}; とかは書けるんだっけ?なんでdecltypeで書けなくする必要があるのか…よう分からん。それと、日記 http://d.hatena.ne.jp/DigitalGhost/20090818/1250621711 のコメントのレスで書いたけど、Tの右辺値参照型の変数 rr があったとして、decltype(rr), decltype((rr))はもっと注意が必要で、前者はT &&で後者はT &になるはずだから、これ適当に書くと割とおかしな事態を招くことになる。とは言っても、それはオーバーロード解決と同じような注意が必要なだけ(それでも気になる人にとってはなかなかに厄介な問題かもしれない)だから、そこまで問題でもないか。書いてるうちに、eを変数または関数の識別子として、decltype(e)とdecltype((e))で型が違うとか全然問題ないように思えてきた。脳内で検証してみたけど、id- expression以外で変な挙動を示すことはなさそうだし、だいたい変数の型をとってきてほしいときにわざわざdecltype((e))と書く人間はいないだろうし、decltype(e)の結果は分かりやすい。ただ、sizeof(e)の型になってほしいというパターンがほしい場合はどうするんだろう…これはdecltypeの結果の型にメタ関数かませばなんとかなるかな?