[英]Getting the number of arguments to a function at compile-time using variadic templates with argument type check in c++
[英]Lambda function with number of arguments determined at compile-time
我想聲明一個具有N個參數的lambda函數,其中N是模板參數。 就像是...
template <int N>
class A {
std::function<void (double, ..., double)> func;
// exactly n inputs
};
我想不出用元函數范式來做這個的方法。
您可以使用嵌套的typedef type
編寫模板n_ary_function
。 此類型可以使用如下:
template <int N>
class A {
typename n_ary_function<N, double>::type func;
};
以下代碼片段包含n_ary_function
的定義:
template <std::size_t N, typename Type, typename ...Types>
struct n_ary_function
{
using type = typename n_ary_function<N - 1, Type, Type, Types...>::type;
};
template <typename Type, typename ...Types>
struct n_ary_function<0, Type, Types...>
{
using type = std::function<void(Types...)>;
};
獲取模板,計數和類型的元template
,並使用N
個類型的副本調用模板:
template<template<class...>class target, unsigned N, class T, class... Ts>
struct repeat_type_N: repeat_type_N<target, N-1, T, T, Ts...> {};
template<template<class...>class target, class T, class... Ts>
struct repeat_type_N<target, 0, T, Ts...> {
typedef target<Ts...> type;
};
template<template<class...>class target, unsigned N, class T>
using repeat_type_N_times = typename repeat_type_N<target, N, T>::type;
現在,我們使用它:
template<typename... Ts> using operation=void(Ts...);
template<unsigned N, class T> using N_ary_op = repeat_type_N_times< operation, N, T >;
template<unsigned N> using N_double_func = N_ary_op<N,double>;
我們測試它:
void three_doubles(double, double, double) {}
int main() {
N_double_func<3>* ptr = three_doubles;
std::function< N_double_func<3> > f = three_doubles;
}
贏了。
在上述系統中double, double, double
您使用double, double, double
究竟是什么完全取決於您。 例如,您可以使用初始化std::function
的lambda。
你可以將double, double, double
打包成template<class...>struct type_list{};
所以你可以將它作為一個參數傳遞給另一個template
,然后專門解壓縮它。
對於大N
遞歸較少的repeat_type
:
// package for types. The typedef saves characters later, and is a common pattern in my packages:
template<class...>struct types{typedef types type;};
// Takes a target and a `types`, and applies it. Note that the base has no implementation
// which leads to errors if you pass a non-`types<>` as the second argument:
template<template<class...>class target, class types> struct apply_types;
template<template<class...>class target, class... Ts>
struct apply_types<target, types<Ts...>>{
typedef target<Ts...> type;
};
// alias boilerplate:
template<template<class...>class target, class types>
using apply_types_t=typename apply_types<target,types>::type;
// divide and conquer, recursively:
template<unsigned N, class T, class Types=types<>> struct make_types:make_types<
(N+1)/2, T, typename make_types<N/2, T, Types>::type
> {};
// terminate recursion at 0 and 1:
template<class T, class... Types> struct make_types<1, T, types<Types...>>:types<T,Types...> {};
template<class T, class Types> struct make_types<0, T, Types>:Types{};
// alias boilerplate:
template<unsigned N, class T>
using make_types_t=typename make_types<N,T>::type;
// all of the above reduces `repeat_type_N_t` to a one-liner:
template<template<class...>class target, unsigned N, class T>
using repeat_type_N_times = apply_types_t<target, make_types_t<N,T>>;
對於大N
,上面可以顯着減少編譯時間,並處理溢出template
堆棧。
你不能直接這樣做。
你可以做這樣的事情
template <unsigned N> class UniformTuple;
template <>
class UniformTuple <0>
{
};
template <unsigned N>
class UniformTuple : public UniformTuple <N-1>
{
public:
template <typename... Args>
UniformTuple (double arg, Args... args)
: UniformTuple <N-1> (args...)
, m_value (arg)
{
}
private:
double m_value;
};
template <int N>
class A
{
std :: function <void (const UniformTuple <N> &)> func;
};
為了完整性,這里是一個沒有遞歸的解決方案:
template <class Ret, class Arg, class Idx>
struct n_ary_function_;
template <class Ret, class Arg, std::size_t... Idx>
struct n_ary_function_<Ret, Arg, std::index_sequence<Idx...>> {
template <class T, std::size_t>
using id = T;
using type = std::function<Ret(id<Arg, Idx>...)>;
};
template <class Ret, class Arg, std::size_t N>
using n_ary_function = typename n_ary_function_<
Ret, Arg, std::make_index_sequence<N>
>::type;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.