具有不同数量参数的函数的模板别名
template alias for function with varying number of arguments
我有一个 class 模板 Foo,它有几个成员,其中一个是 Bar 类型的函数 bar:
template<std::size_t N>
class Foo
{
...
Bar<N> bar;
...
};
我希望 Bar<2>
成为函数 double (* )(double, double)
(或可能 std::function<double(double, double)>
)的模板别名。同样,我希望 Bar<3>
成为函数 double (* )(double, double, double)
(或可能 std::function<double(double, double, double)>
)的模板别名。这意味着 N
应该指定函数 bar 采用的双参数的数量。
我设法接近这种行为的唯一方法是使用模板别名
template <std::size_t N>
using Bar = double (* )(std::array<double, N>& eval);
然而,通过这种方式,我无法以自然方式调用函数 bar
bar(x,y,z)
。
是否可以获得我想要的行为?
有了额外的层,你可以这样做:
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
是 C++14,但可以在 C++11 中实现。
另一个选项,没有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 *;
我有一个 class 模板 Foo,它有几个成员,其中一个是 Bar 类型的函数 bar:
template<std::size_t N>
class Foo
{
...
Bar<N> bar;
...
};
我希望 Bar<2>
成为函数 double (* )(double, double)
(或可能 std::function<double(double, double)>
)的模板别名。同样,我希望 Bar<3>
成为函数 double (* )(double, double, double)
(或可能 std::function<double(double, double, double)>
)的模板别名。这意味着 N
应该指定函数 bar 采用的双参数的数量。
我设法接近这种行为的唯一方法是使用模板别名
template <std::size_t N>
using Bar = double (* )(std::array<double, N>& eval);
然而,通过这种方式,我无法以自然方式调用函数 bar
bar(x,y,z)
。
是否可以获得我想要的行为?
有了额外的层,你可以这样做:
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
是 C++14,但可以在 C++11 中实现。
另一个选项,没有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 *;