先週名古屋にてBoost.勉強会#5が開催されました.
それとは直接関係ないのですが,行きの電車の中でBoost.Variantの仕様に関して疑問をもってTwitterでつぶやいたところ@cpp_akiraさんより回答をいただいて,それがすごく興味深い内容だったのでそのやりとりをこちらでメモ.
boost::variant<T1,T2,...>のオブジェクトtがあったときにt.get<T1>()と書きたいなぁ,とか…. boost::get<T1>(t)となってるのはどういう意図or理由なんでしょう.
@mrxptn
すずき
@mrxptn template限定子が必要になるからです。
@cpp_akira
Faith and Brave
ん?template限定子って何だ…?
ということでググります.
@cpp_akiraさんのブログが最初に出てきました.
http://d.hatena.ne.jp/faith_and_brave/20080128/1201510970
えっ…,こんな構文初めて見た….
で,このことがboost::variantにも影響してて,
@mrxptn ですです。テンプレート内でメンバ関数テンプレートを呼ぶときにだけtemplateが必要になって混乱するからですね。
@cpp_akira
Faith and Brave
なるほど.
ライブラリアンの方はよく考えてるんだなー.
「できること」と「するべきこと」は違うってことですね.
仮にメンバとしてgetが実装されていたとしたら,
つまり,普通にメンバだからつって何も考えず呼び出しコード書いてtemplate限定子ないって怒られても….
とは言っても,
@mrxptn まぁでも、Boost.MultiIndexを使ってるとまれによく必要になりますw
@cpp_akira
Faith and Brave
fm...
なるほど.
調べた限りだとまだよくわかんないので,宿題ということで.
で,少しだけ関係あるんじゃないかと勝手に思ってる話.
template限定子は,メンバ関数の実引数から型を推定できないとき…なので,テンプレート化の対象が型じゃなくて値のときは当然問題なくて,Boost.Tupleのgetメソッドは普通にn番目の要素をテンプレート実引数の形で指定できます.
boost::tuple<int, int> t = boost::make_tuple(10, 20); std::cout << t.get<0>() << std::endl; std::cout << t.get<1>() << std::endl; std::cout << t.get<2>() << std::endl; //compile error!!!!!
ですが,C++0xでのstd::tupleでは,getはグローバルに追い出されました.
std::tuple<int, int> t(10, 20); std::cout << std::get<0>(t) << std::endl; std::cout << std::get<1>(t) << std::endl; std::cout << std::get<2>(t) << std::endl; //compile error!!!!!
これはさっきのvariantに合わせるための変更なのかなー,などと思っています.
いや,そんなのたぶんディスカッションの記録見れば答えがあるんでしょうけど.