インスタンス化のために固定されているが、テンプレートパラメータによって可変の引数の数を持つテンプレートメソッド

マイケル

関数の引数の数がテンプレートパラメーターに依存するように、整数のテンプレートパラメーターを使用してテンプレートクラスの関数を定義したいと思います。次に例を示します。

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関数を作成できますが、基本的に同じコードを非C ++風に繰り返す習慣があります。さらに、intテンプレートパラメータのすべての可能な値に特化する必要はありません。

?の値ごとに特殊化コードを記述せずに、型の引数Point<Coord,dim>::Set()を正確に受け取る関数を実装することは可能ですか?dimCoorddim

バリー

Boost.Hanaが使用するトリックを使用できますgetNth

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>;

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ