在模板参数中扩展类型 N 次
Expand a type N times in template parameter
我有以下问题:
template< std::size_t N >
class A
{
std::function< std::size_t( /*std::size_t,....,std::size_t <- N-times*/) > foo;
};
如您在上面所见,我尝试将 std::function<...> foo
声明为 class A
的成员。在这里,我希望 foo 具有 return 类型 std::size_t
(这没问题)并且作为输入,我将传递 N 次类型 std::size_t
但我不知道如何。有没有可能?
非常感谢。
好的,这很有趣。这是我的解决方案:
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)
您可以使用 std::index_sequence
:
template<std::size_t N, typename = std::make_index_sequence<N>>
struct A;
template<std::size_t N, std::size_t... S>
struct A<N, std::index_sequence<S...>> {
std::function<std::size_t(decltype(S)...)> foo;
};
如果你愿意,你也可以定义扩展到什么类型:
template<typename T, std::size_t N, typename = std::make_index_sequence<N>>
struct A;
template<typename T, std::size_t N, std::size_t... S>
struct A<T, N, std::index_sequence<S...>> {
template<std::size_t>
using type = T;
std::function<std::size_t(decltype(S)...)> foo;
};
对于任意类型而不仅仅是 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;
};
我有以下问题:
template< std::size_t N >
class A
{
std::function< std::size_t( /*std::size_t,....,std::size_t <- N-times*/) > foo;
};
如您在上面所见,我尝试将 std::function<...> foo
声明为 class A
的成员。在这里,我希望 foo 具有 return 类型 std::size_t
(这没问题)并且作为输入,我将传递 N 次类型 std::size_t
但我不知道如何。有没有可能?
非常感谢。
好的,这很有趣。这是我的解决方案:
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)
您可以使用 std::index_sequence
:
template<std::size_t N, typename = std::make_index_sequence<N>>
struct A;
template<std::size_t N, std::size_t... S>
struct A<N, std::index_sequence<S...>> {
std::function<std::size_t(decltype(S)...)> foo;
};
如果你愿意,你也可以定义扩展到什么类型:
template<typename T, std::size_t N, typename = std::make_index_sequence<N>>
struct A;
template<typename T, std::size_t N, std::size_t... S>
struct A<T, N, std::index_sequence<S...>> {
template<std::size_t>
using type = T;
std::function<std::size_t(decltype(S)...)> foo;
};
对于任意类型而不仅仅是 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;
};