获取函数参数类型作为元组
Get function arguments type as tuple
问题
Given any function (or callable) type Function
, how can I get its all arguments types as a tuple type ?
例如,我需要一个特征function_traits<Function>::arguments
,其中:
int f();
typename function_traits<decltype(f)>::arguments // => gives me std::tuple<>
void g(int);
typename function_traits<decltype(g)>::arguments // => gives me std::tuple<int>
void h(int, int);
typename function_traits<decltype(h)>::arguments // => gives me std::tuple<int, int>
我的想法
第一个
我需要获取参数的大小,幸运的是boost已经实现了function_traits<F>::arity
然后
从 1 生成一个 std::integer_sequence
到 artify,将其映射到参数类型,但问题来了,要映射 integer_sequence
,我需要这样的东西:
function_traits<F>::arg_type<N> // -> N-th arg_type
但 boost 只提供了这个:
function_traits<F>::argN_type
问题
如何实施 function_traits<F>::arg_type<N>
?我可以使用最高为 c++17
的 c++ 标准
像这样:
#include <tuple>
template<typename x_Function> class
function_traits;
// specialization for functions
template<typename x_Result, typename... x_Args> class
function_traits<x_Result (x_Args...)>
{
public: using arguments = ::std::tuple<x_Args...>;
};
用法示例:
#include <type_traits>
int foo(int);
using foo_arguments = function_traits<decltype(foo)>::arguments;
static_assert(1 == ::std::tuple_size<foo_arguments>::value);
static_assert(::std::is_same_v<int, ::std::tuple_element<0, foo_arguments>::type>);
来不及玩了?
您可以使用 C++17,所以...使用 std::function
演绎指南怎么样?
template <typename T>
struct function_traits
{
template <typename R, typename ... As>
static std::tuple<As...> pro_args (std::function<R(As...)>);
using arguments = decltype(pro_args(std::function{std::declval<T>()}));
};
下面是一个完整的编译示例
#include <tuple>
#include <functional>
#include <type_traits>
int f ();
void g (int);
void h (int, int);
template <typename T>
struct function_traits
{
template <typename R, typename ... As>
static std::tuple<As...> pro_args (std::function<R(As...)>);
using arguments = decltype(pro_args(std::function{std::declval<T>()}));
};
int main ()
{
static_assert(std::is_same_v<std::tuple<>,
function_traits<decltype(f)>::arguments>);
static_assert(std::is_same_v<std::tuple<int>,
function_traits<decltype(g)>::arguments>);
static_assert(std::is_same_v<std::tuple<int, int>,
function_traits<decltype(h)>::arguments>);
}
问题
Given any function (or callable) type
Function
, how can I get its all arguments types as a tuple type ?
例如,我需要一个特征function_traits<Function>::arguments
,其中:
int f();
typename function_traits<decltype(f)>::arguments // => gives me std::tuple<>
void g(int);
typename function_traits<decltype(g)>::arguments // => gives me std::tuple<int>
void h(int, int);
typename function_traits<decltype(h)>::arguments // => gives me std::tuple<int, int>
我的想法
第一个
我需要获取参数的大小,幸运的是boost已经实现了function_traits<F>::arity
然后
从 1 生成一个 std::integer_sequence
到 artify,将其映射到参数类型,但问题来了,要映射 integer_sequence
,我需要这样的东西:
function_traits<F>::arg_type<N> // -> N-th arg_type
但 boost 只提供了这个:
function_traits<F>::argN_type
问题
如何实施 function_traits<F>::arg_type<N>
?我可以使用最高为 c++17
像这样:
#include <tuple>
template<typename x_Function> class
function_traits;
// specialization for functions
template<typename x_Result, typename... x_Args> class
function_traits<x_Result (x_Args...)>
{
public: using arguments = ::std::tuple<x_Args...>;
};
用法示例:
#include <type_traits>
int foo(int);
using foo_arguments = function_traits<decltype(foo)>::arguments;
static_assert(1 == ::std::tuple_size<foo_arguments>::value);
static_assert(::std::is_same_v<int, ::std::tuple_element<0, foo_arguments>::type>);
来不及玩了?
您可以使用 C++17,所以...使用 std::function
演绎指南怎么样?
template <typename T>
struct function_traits
{
template <typename R, typename ... As>
static std::tuple<As...> pro_args (std::function<R(As...)>);
using arguments = decltype(pro_args(std::function{std::declval<T>()}));
};
下面是一个完整的编译示例
#include <tuple>
#include <functional>
#include <type_traits>
int f ();
void g (int);
void h (int, int);
template <typename T>
struct function_traits
{
template <typename R, typename ... As>
static std::tuple<As...> pro_args (std::function<R(As...)>);
using arguments = decltype(pro_args(std::function{std::declval<T>()}));
};
int main ()
{
static_assert(std::is_same_v<std::tuple<>,
function_traits<decltype(f)>::arguments>);
static_assert(std::is_same_v<std::tuple<int>,
function_traits<decltype(g)>::arguments>);
static_assert(std::is_same_v<std::tuple<int, int>,
function_traits<decltype(h)>::arguments>);
}