c++ - 如何从参数包中获取所有参数的类型?

标签 c++ templates c++11 c++14 typetraits

我有以下代码,其中我使用模板化的 static 方法 random 定义了 struct quick 并进行了一些专门化:

(我使用了其他 SO 答案中的 function_traits。附在底部以供引用。)

struct quick
{
  template <typename T>
  static T random();

  template <typename F>
  static void check(F f)
  {

    constexpr auto arity = function_traits<F>::arity; // easy :)
    std::cout << arity << std::endl;
    typedef typename function_traits<F>::template arg<0>::type type0; // easy:)
    // how to get all types of all F's parameters?
  }
};

template <>
std::string quick::random<std::string>()
{
  return std::string("test");
}

template <>
int quick::random<int>()
{
  return 1;
}

我想在 check 中获取所有类型的 F 参数,这样我就可以生成一个带有随机条目的 tuple(基于在我的随机方法特化上)。

像这样:

auto t0 = std::make_tuple(quick::random<AllTypes>()...); //pseudo code
auto t =
    std::make_tuple(quick::random <
                                  function_traits<F>::template arg<std::make_index_sequence<arity>>::type...
                                  >
                                  ()...
                     );

我试过类似的东西:

template<typename F, typename ...TIdxs>
using ArgTypes = typename function_traits<F>::template arg<TIdxs>::type...;

// ...
// inside check

typedef ArgTypes<F, std::make_index_sequence<arity>> types;

但惨败:

main.cpp:80:72: error: expected ‘;’ before ‘...’ token
 using ArgTypes = typename function_traits<F>::template arg<TIdxs>::type...;
                                                                        ^
main.cpp: In static member function ‘static void quick::check(F, D)’:
main.cpp:98:15: error: ‘ArgTypes’ does not name a type
       typedef ArgTypes<F, std::make_index_sequence<arity>> types;

我使用了来自 thisfunction traits 实用程序所以回答。

template <typename T>
struct function_traits : function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
    enum { arity = sizeof...(Args) };
    // arity is the number of arguments.

    typedef ReturnType result_type;

    template <size_t i>
    struct arg
    {
        typedef typename std::tuple_element<i, std::tuple<Args...>>::type type;
        // the i-th argument is equivalent to the i-th tuple element of a tuple
        // composed of those arguments.
    };
};

最佳答案

请注意,在 function_traits 中,您已经拥有所有参数类型。您所要做的就是公开它们:

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
    enum { arity = sizeof...(Args) };

    using result_type = ReturnType;

    using all_args = std::tuple<Args...>; // <-- add this

    template <size_t i> // <-- consider making this an alias template
    using arg = std::tuple_element_t<i, all_args>;
};

现在,获取所有函数参数只是function_traits<F>::all_args .


如果你不想改变function_traits ,我们只需要添加一个外部元函数:

template <class F, class = std::make_index_sequence<function_traits<F>::arity>>
struct all_args;

template <class F, size_t... Is>
struct all_args<F, std::index_sequence<Is...>> {
    using type = std::tuple<typename function_traits<F>::template arg<Is>::type...>;
};

template <class F>
using all_args_t = typename all_args<F>::type;

关于c++ - 如何从参数包中获取所有参数的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38688041/

相关文章:

c++ - 如何检查模板参数是否为迭代器类型?

c++ - 枚举类不是类或命名空间

c++ - 使用 std::initializer_list 的显式构造函数和初始化

c++ - 为什么 Valgrind 不检测未初始化变量的使用?

c++ - 修改 SFINAE 习语以使用 std::is_arithmetic 检查函数的返回类型

c++ - 错误 : Expected initializer before "file",,包括 ifstream。

c++ - 当 template<typename, value...> 时强制特定重载

c++ - 从字符串中删除行注释

c++ - pugixml 不生成任何输出

c++ - 合并 2 个不同的 AVL 树