c++ 获取函数参数类型为元组

xesrikrc  于 2023-08-09  发布在  其他
关注(0)|答案(3)|浏览(114)

问题

给定任何函数(或可调用)类型Function,如何将其所有参数类型作为元组类型?
例如,我需要一个trait 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到artify生成一个std::integer_sequence,将其Map到arguments类型,但问题来了,要Mapinteger_sequence,我需要这样的东西:

function_traits<F>::arg_type<N> // -> N-th arg_type


但boost仅提供以下功能:

function_traits<F>::argN_type

提问

如何实现function_traits<F>::arg_type<N>?我可以使用c标准到c17

c3frrgcw

c3frrgcw1#

大概是这样的:

#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>);


online compiler

kb5ga3dv

kb5ga3dv2#

玩得太晚了吗?
你可以用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>);
 }

vyswwuz2

vyswwuz23#

现在是几年后,但我有一个非常有效的(免费)解决方案,如果你仍然需要它(如果你没有锁定到Boost)。我对我发现的处理函数traits的解决方案不满意,包括Boost的(既不是“function_traits”也不是“callable_traits”),我写了自己的解决方案,并在GitHub上为C++开发人员社区提供。我相信它是目前你能找到的同类库中最完整的(专业编写和完整文档)。
参见https://stackoverflow.com/a/76253527/698767(以及此处引用的链接)。
请注意,这里的例子也解决了你的问题。

相关问题