鍋あり谷あり

テーマを決めずに適当に書いています。

型による推論の続き

昨日の記事 id:Nabetani:20051108:p3 を書いてすぐに寝たんだが、寝ている間に。
コンストラクタをテンプレートメンバ関数にすれば、変数が5個でも10個でもコンストラクタの数があまり多くならないということに気がついた。
具体的にはこんな感じ:

template< typename t > struct xtuple_base
{
  t m;
  xtuple_base( const t & _m ) : m( _m ){}
  t & get(){  return m;  }
};


template< typename t0, typename t1 > struct xtuple
  : public xtuple_base< t0 >
  , public xtuple_base< t1 >
{
  template< typename _t0, typename _t1 >
  xtuple( const _t0 & _m0, const _t1 & _m1 )
  : xtuple_base< _t0 >( _m0 )
  , xtuple_base< _t1 >( _m1 )
  {}
  template< typename t >
  t & get(){  return xtuple_base< t >::get(); }
};
void test()
{
  xtuple< long, double > foo( 1, 2.0 ); // 昨日のバージョンでは通るが、今日のバージョンではコンパイルエラー
  xtuple< float, char > bar( 'c', 3.0f );
  xtuple< short, long > baz( static_cast<short>(100), 4L );
  cout << bar.get<char>() << ", " << bar.get<float>() << endl; // -> c, 3
  cout << baz.get<short>() << ", " << baz.get<long>() << endl; // -> 100, 4
}

相変わらず主要部分だけで、型変換演算子や比較関数は用意していない。全部 public だし。
上記の通り、昨日書いたバージョンとはちょっと動作が異なる。コンストラクタの引数の型が厳密に一致してなくてはいけない。微妙に使いにくいような。
やっぱりたくさんコンストラクタを作った方がいいような。

ところで。
short のリテラルって、書けないんだっけ。いや、L'\1' で short になるかもしれないけど、それは short とは限らないわけで。
1 : int
1U : unsigned int
1L : long
1UL : unsigned long
1.0 : double
1.0F : float
'\1' : char
L'\1' : wchar_t
true : bool
リテラルが書けないような気がするのは、short, unsigned short, signed char, unsigned char の4つ。
あ。
マイクロソフトコンパイラなら、
1i16 とか書けるけど、これはこれでやっぱり short とは限らないような気もする。コンパイラ依存コードではあるが、ターゲットが異なれば short の長さも変わるかもしれない。gnu エクステンションも何かあるのかな。