在模板参数中展开N次类型

时间:2016-10-12 09:29:13

标签: c++ templates c++14 std-function

我有以下问题:

template< std::size_t N >
class A
{
  std::function< std::size_t( /*std::size_t,....,std::size_t <- N-times*/) > foo;
};

如上所示,我尝试将std::function<...> foo声明为类A的成员。在这里,我希望foo具有返回类型std::size_t(这没有问题)作为输入,我将传递N次类型std::size_t,但我不知道如何。有可能吗?

非常感谢提前。

3 个答案:

答案 0 :(得分:12)

您可以使用std::index_sequence

template<typename>
struct AHelper;

template<std::size_t... S>
struct AHelper<std::index_sequence<S...>> {
    std::function<std::size_t(decltype(S)...)> foo;
};

template<std::size_t N>
struct A : AHelper<std::make_index_sequence<N>> {};

Live example at coliru

如果您愿意,还可以定义它展开的类型:

template<typename, typename>
struct AHelper;

template<typename T, std::size_t... S>
struct AHelper<T, std::index_sequence<S...>> {
    template<std::size_t>
    using type = T;

    std::function<std::size_t(type<S>...)> foo;
};

template<typename T, std::size_t N>
struct A : AHelper<T, std::make_index_sequence<N>> {};

答案 1 :(得分:2)

对于任意类型而不仅仅是size_t,只需编写辅助别名:

template<class T, size_t>
using Type = T;

template<std::size_t... S>
struct AHelper<std::index_sequence<S...>> {
    std::function<size_t(Type<MyArbitraryTypeHere, S>...)> foo;
};

答案 2 :(得分:1)

好的,这很有趣。这是我的解决方案:

namespace details {
template <size_t N, class F = size_t()>
struct Function_type_helper {};

template <size_t N, class... Args>
struct Function_type_helper<N, size_t(Args...)> {
    using Type = typename Function_type_helper<N - 1, size_t(Args..., size_t)>::Type;
};

template <class... Args>
struct Function_type_helper<0, size_t(Args...)> {
    using Type = size_t(Args...);
};

template <size_t N, class F = size_t()>
using Function_type_helper_t = typename Function_type_helper<N, F>::Type;

static_assert(std::is_same_v<Function_type_helper_t<3>, size_t(size_t, size_t, size_t)>);
} // ns details

template<size_t N>
struct A
{
  std::function<details::Function_type_helper_t<N>> foo;
};

这可以通过递归创建类型size_t(size_t, size_t, ..., size_t)

来实现

例如:

H<3>::Type == H<3, size_t()>::Type ==
              H<2, size_t(size_t)>::Type == 
              H<1, size_t(size_t, size_t)>::Type ==
              H<0, size_t(size_t, size_t, size_t)>::Type ==
              size_t(size_t, size_t, size_t)