从可变参数模板调用仿函数

Pet*_*ter 0 c++ variadic-templates c++11

是否可以编写可变参数模板类

template<typename Functor, int... D>
struct Foo
{
    void bar()
    {
        // ???
    }
};
Run Code Online (Sandbox Code Playgroud)

这相当于

template<typename Functor, int D0>
struct Foo<Functor, D0>
{
    void bar()
    {
        Functor f;
        double d0[D0];
        f(d0);
    }
};

template<typename Functor, int D0, int D1>
struct Foo<Functor, D0, D1>
{
    void bar()
    {
        Functor f;
        double d0[D0];
        double d1[D1];
        f(d0, d1);
    }
};

// And so on...
Run Code Online (Sandbox Code Playgroud)

也就是说,传递给仿函数的参数数量等于模板参数的数量.参数应该在堆栈上分配.

Jar*_*d42 5

通过以下方式在堆栈上使用参数的版本std::tuple:

// Helper class to be able to use expansion of std::get<Index>(tuple)
template <int... Is> struct index_sequence {};

// Following create index_sequence<0, 1, 2, .., sizeof...(Is) - 1>
template <int Index, int... Is>
struct make_index_sequence { // recursively build a sequence of indices
    typedef typename make_index_sequence<Index - 1, Index -1, Is...>::type type;
};

template <int... Is>
struct make_index_sequence<0, Is...> { // stop the recursion when 0 is reached
    typedef index_sequence<Is...> type;
};

template<typename Functor, int... Ds>
struct Foo
{
    void bar()
    {
        bar(typename make_index_sequence<sizeof...(Ds)>::type());
    }
private:
    template <int... Is>
    void bar(index_sequence<Is...>)
    {
        Functor f;
        std::tuple<double[Ds]...> t; // std::tuple<doudle[D0], double[D1], ..>
        f(std::get<Is>(t)...);       // f(std::get<0>(t), std::get<1>(t), ..);
    }
};
Run Code Online (Sandbox Code Playgroud)