在编译时迭代函数参数类型

时间:2015-05-28 08:46:28

标签: c++ templates

在c ++中有没有办法在编译时迭代函数参数类型?我想做这样的事情:

struct null_type {};

float foo(int, bool, char);

get_param_type<foo, 0>::type float_var; // return type
get_param_type<foo, 1>::type int_var; // first arg type
get_param_type<foo, 2>::type bool_var; // second arg type
get_param_type<foo, 3>::type char_var; // third arg type
get_param_type<foo, 4>::type null_type_var;

2 个答案:

答案 0 :(得分:4)

您可以自己轻松编写。首先,将函数参数类型打包到元组中:

#include <tuple>

template <typename> struct FnArgs;

template <typename R, typename ...Args>
struct FnArgs<R(Args...)>
{
    using type = std::tuple<Args...>;
};

现在您可以使用标准元组API来访问元素:

using FT = FnArgs<decltype(foo)>::type;

std::tuple_element<0, FT> x;

如果需要,可以轻松添加指针到成员函数的进一步特化。

(你不能轻易绕过decltype,因为对于非类型模板参数(尚未)没有类型推论。)

答案 1 :(得分:3)

这是一个使用null_type作为越界索引的版本:

template <typename, std::size_t, typename = void>
struct get_param_type
{
    using type = null_type;
};

template <typename Ret, typename... Args, std::size_t N>
struct get_param_type<Ret(Args...), N, std::enable_if_t<N < (1+sizeof...(Args))>>
{
    using type = typename std::tuple_element<N,std::tuple<Ret,Args...>>::type;
};