C++1xでぜひいれて欲しい機能
0xじゃないよその次の話だよ。
C++って多重継承あるから難しいけど、基底クラスの型を取得する構文がほしい。
例えばdeclbase()とかbaseof()とか...
前々から思ったんだけど、boostのコードを読んでてやっぱり思った。
というのもboost.compressed_pairの定義が非常に熱い。引用して大丈夫なのかな?多分大丈夫。
template <class T1, class T2> class compressed_pair : private ::boost::details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch< T1, T2, ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value, ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value> { private: typedef details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch< T1, T2, ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value, ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value> base;
もう...言語レベルでサポートしていいよね...
これが
private: typedef declbase( compressed_pair< T1, T2 >, 0 ) base;
とか
private: typedef baseof( compressed_pair< T1, T2 >, 0 ) base;
とか
template <class T1, class T2> class compressed_pair : private ::boost::details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch< T1, T2, ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value, ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value> -> base
とか
template <class T1, class T2> class compressed_pair : private typedef ::boost::details::compressed_pair_imp<T1, T2, ::boost::details::compressed_pair_switch< T1, T2, ::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value, ::boost::is_empty<T1>::value, ::boost::is_empty<T2>::value>::value> base
とか。
最初の2つは多重継承の解決のために第2引数にインデックスをいれてみたり。でも、基底クラスがprivateだったらとかあるから多分ボツ。
で、残りの2つが多分有力なパターン(とか勝手に考えてる)。->を使って関数みたく型を書くとか、typedefをそういうとこに書けるようにするもの。
こっちはその型名が基底クラスと同じアクセス修飾子をもって、declbaseとかbaseofみたいに見えてほしくない型も見えてしまうのを防げる。スマートだ。
個人的にはtypedefがいい気がする。意味もわかり易いし。
ちなみにaliasは無し。というのも基底クラスの型はcomplete typeになるはずなので、aliasみたいなuncompleteな書き方ができるのは間違えが発生しそう。
多重継承とか書いてみると...
template < typename... > class base1 {}; template < template < typename... > class Base, typename... Args > class base2 : private Base< Args... > {}; class derived : private typedef base1< int, std::string > _b1, public typedef base2< base1, int, std::string > _b2 {}; int main( void ) { //derived::_b1 b1; // _b1はprivateな型名 derived::_b2 b2; // _b2はpublicなので問題無し }
スマートになると思うんだがどうだろう。