template alias for function with varying number of arguments

78 views Asked by At

I have a class template Foo which has several members, one of which is a function bar of type Bar:

template<std::size_t N>
class Foo
{
    ...
    Bar<N> bar;
    ...
};

I would like Bar<2> to be a template alias for a function double (* )(double, double) (or possibly std::function<double(double, double)>). Similarly, I want Bar<3> to be a template alias for a function double (* )(double, double, double) (or possibly std::function<double(double, double, double)>). This means that N should specify the number of double arguments that the function bar takes.

The only way I managed to get anywhere close to this behaviour, is by using the template alias

template <std::size_t N>
using Bar = double (* )(std::array<double, N>& eval);

In this way, however, I can not call the function bar in its natural way bar(x,y,z).

Is it possible to get the behaviour that I want?

2

There are 2 answers

3
Jarod42 On BEST ANSWER

With extra layer, you might do:

template <typename T>
struct BarHelper;

template <std::size_t ... Is>
struct BarHelper<std::index_sequence<Is...>>
{
private:
    template <std::size_t, typename T>
    using always_t = T;
public:
    using type = double (*) (always_t<Is, double>...);
};

template <std::size_t N>
using Bar = typename BarHelper<std::make_index_sequence<N>>::type;

std::index_sequence is C++14, but can be implemented in C++11.

0
Oliv On

An other option, without index_sequence:

template<class T> 
struct add_double_arg;

template<class R,class...Args>
struct add_double_arg<R(Args...)>{
    using type = R(Args...,double);
};

template<int N,template<class> class Transform,class Init>
struct repeat{
    using type = typename Transform<
           typename repeat<N-1,Transform,Init>::type
                  >::type;
};
template<template<class> class Transform,class Init>
struct repeat<0,Transform,Init>{
    using type = Init;
};

template<int N>
using Bar = typename repeat<N,add_double_arg,double()>::type *;