2015-10-02 10 views
9

関数の引数の数がテンプレートパラメータに依存するように、整数テンプレートパラメータでテンプレートクラスの関数を定義します。ここでは例です:私はこのコードをコンパイルしたいインスタンス化のために引数が固定されているが、テンプレートパラメータによって可変であるテンプレートメソッド

template< class Coord, int dim > 
class Point { 
    Coord mCoords[ dim ]; 
public: 
    void Set(/* I want exactly dim Coord arguments here. */); 
}; 

Point<double,2> pt2d; 
pt2d.Set(25, 32); 
Point<double,3> pt3d; 
pt3d.Set(25, 32, 100); 

と失敗するには、このコード:

Point<double,2> pt2d; 
pt2d.Set(25, 32, 100); // Too many arguments 
Point<double,3> pt3d; 
pt3d.Set(25, 32);  // Too few arguments 

今、私は手動で小さい寸法でPointを特化することができます無関係のSet関数を持っているが、私は本質的に同じコードun-C++を繰り返すという習慣を見つける。さらに、intテンプレートパラメータのすべての可能な値を特化する必要はありません。

それはdimの値ごとに専門のコードを記述せずにタイプCoordの正確dim引数を取るPoint<Coord,dim>::Set()機能を実装することは可能ですか?

答えて

10

あなたがgetNthためBoost.Hanaが使用するトリックを使用することができます。

template <typename Coord, int dim, typename = std::make_index_sequence<dim>> 
struct Point; 

template <typename Coord, int dim, size_t... Ignore> 
struct Point<Coord, dim, std::index_sequence<Ignore...>> 
{ 
    void Set(decltype(Ignore, Coord{})... args) 
    { 
     // ... 
    } 
}; 

Ignoreを隠す長いバージョンは少し醜さ(とCoordデフォルト以外の、構成可能秒間動作します。

template <typename... > struct typelist { }; 

template <int N, typename T, typename = std::make_index_sequence<N>> 
struct repeat; 

template <int N, typename T> 
using repeat_t = typename repeat<N, T>::type; 

template <int N, typename T, size_t... Idx> 
struct repeat<N, T, std::index_sequence<Idx...>> 
{ 
    template <size_t > 
    struct makeT { using type = T; }; 

    using type = typelist<typename makeT<Idx>::type...>; 
}; 

そして、代わりにrepeat_tに特化..)いくつかのメタプログラミングの定型を追加することです。これをネームスペースで非表示にすると、ユーザはそれを壊すことができなくなります。

namespace details { 
    template <typename Coord, int dim, typename = repeat_t<dim, Coord>> 
    struct Point; 

    template <typename Coord, int dim, typename... dimCoords> 
    struct Point<Coord, dim, typelist<dimCoords...>> 
    { 
     void Set(dimCoords... args) 
     { 

     } 
    }; 
} 

template <typename Coord, int dim> 
using Point = details::Point<Coord, dim>; 
+0

'ints'は' index_sequence'から推測できますか? –

+1

@PiotrSkotnickiはい。それにもかかわらず、それを 'size_t'に変更しました。 – Barry

関連する問題