にゃははー

はへらー

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なので問題無し
}

スマートになると思うんだがどうだろう。