Reputation: 413
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?
Upvotes: 3
Views: 82
Reputation: 18051
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 *;
Upvotes: 1
Reputation: 217255
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.
Upvotes: 4