如何定义五次相同参数类型的函数类型

时间:2014-07-10 00:37:14

标签: c++ c++11 function-pointers

我想知道是否可以定义一个带n个参数的函数类型,只需要知道n以及这些参数的类型。

例如,我们可以有类似的东西:

template<int N> struct test {
  typedef void(*)(E,E,E,...) fct; //E is written N times
};

在C ++ 11中,很容易使用递归来实现具有N次相同类型的可变参数模板,但我不知道如何将其转换为有效的函数指针类型。

当我输入这些词语时,解决方案来找我。我会自己回答,所以知识可以在将来帮助某人。

3 个答案:

答案 0 :(得分:2)

如果您想要一个更简单的解决方案,您可以将该功能设为std::array<T, N>。直接在括号内初始化数组,使其看起来像一个普通的函数调用:

foo({1, 2, 3})  // to pass a std::array<int, 3>

答案 1 :(得分:1)

在我打字的时候,我突然想到了C ++ 11中的解决方案。 诀窍是使用通用Fct模板类型,并使用variadic模板类型将其专门化为函数“specialization”的参数。

template< typename Fct, typename NewArg > struct functional_append_arg;
template< typename Ret, typename... Args, typename NewArg >
struct functional_append_arg< Ret(Args...), NewArg >
    { using type = Ret(Args...,NewArg); };
template< typename Ret, typename Arg, int N> struct functional_repeat_arg;
    { using type = functional_append_arg< functional_repeat_arg<Ret,Arg,N-1>::type, Arg >::type; };
template< typename Ret, typename Arg> struct functional_repeat_arg<Ret,Arg,0>;
    { using type = Ret(); }

答案 2 :(得分:0)

我们可以再次利用索引技巧来代替递归可变参数技术。

#include <cstddef>
#include <utility>

template <typename T, std::size_t N>
struct repeat {
  private:

  /* Map any index to T. */
  template <std::size_t>
  using T_ = T;

  /* Function pointer that takes Ts. */
  template <typename... Ts>
  using Fn = void (*)(Ts...);

  /* A function returning void (*)(T...). */
  template <std::size_t... Is>
  static Fn<T_<Is>...> impl(std::index_sequence<Is...>);

  public:

  /* Get the return type of impl. */
  using type = decltype(impl(std::make_index_sequence<N>()));

};  // repeat

static_assert(std::is_same<repeat<int, 5>::type,
                           void (*)(int, int, int, int, int)>::value, "");