从模板化类中提取类型

时间:2016-03-31 17:20:09

标签: c++ templates types c++14

我正在为任何模板化类实现类型提取器extract_type<Class, nth-type>。示例用法如下所示:

template <int, short, float, double, char> class C;

extract_type<C, 0>::type => int
extract_type<C, 1>::type => short
extract_type<C, 2>::type => float
extract_type<C, 3>::type => double
extract_type<C, 4>::type => char

这是我的实施。

// extract_type: recursive definition.
template <template <typename...> class C, size_t idx, typename T, typename... RestT> 
struct extract_type;

// extract_type: base
template <template <typename...> class C, typename T, typename... RestT>
struct extract_type< C<RestT...>, 0, RestT... > { 
  using type = T;
};


// extract_type: recursive definition.
template <template <typename...> class C, size_t idx, typename T, typename... RestT>
struct extract_type : public extract_type< C<RestT...>, idx-1, RestT... > { 
};

然而,编译器抱怨

  模板参数列表中参数1的

类型/值不匹配'模板类C,long unsigned int idx,class T,class ... RestT&gt; struct OpenCluster :: extract_type'   struct extract_type&lt; void,0,RestT ...&gt;

我如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

你的意思是那样的(最小的,有效的例子)吗?

aenum

这将是您的代码(固定版和工作版):

#include<tuple>
#include<iostream>
#include<type_traits>

template<int, typename...>
struct extract_type;

template<int N, typename T, typename... O, template<typename...> typename U>
struct extract_type<N, U<T, O...>>: extract_type<N-1, U<O...>> { };

template<typename T, typename... O, template<typename...> typename U>
struct extract_type<0, U<T, O...>> { using type = T; };

int main() {
    using MyTuple = std::tuple<int, double, char>;
    // true
    std::cout << std::is_same<extract_type<1, MyTuple>::type, double>::value << std::endl;
    // false
    std::cout << std::is_same<extract_type<2, MyTuple>::type, double>::value << std::endl;
}

非常难看,不是吗?

问题在于您将其定义为传递与其参数分开的模板类,以便前者在#include<tuple> #include<iostream> #include<type_traits> // extract_type: recursive definition. template <template <typename...> class C, size_t idx, typename T, typename... RestT> struct extract_type; // extract_type: base template <template <typename...> class C, typename T, typename... RestT> struct extract_type< C, 0, T, RestT... > { using type = T; }; // extract_type: recursive definition. template <template <typename...> class C, size_t idx, typename T, typename... RestT> struct extract_type : public extract_type< C, idx-1, RestT... > { }; int main() { // true std::cout << std::is_same<extract_type<std::tuple, 1, int, double, char>::type, double>::value << std::endl; // false std::cout << std::is_same<extract_type<std::tuple, 2, int, double, char>::type, double>::value << std::endl; } 中没有任何角色。
这意味着您可以将其定义为:

extract_type

因此,它将被用作:

template <size_t idx, typename T, typename... RestT> 
struct extract_type;

结果相同:extract_type<1, int, double, char>::type

你的例子中有错误(当然,除了句法错误之外)?

答案 1 :(得分:-1)

这是我的实施。

#include "iostream"

template<class ...Ts> struct C {};

template<int N, class ...Ts>
struct extract_type_impl;

template<class C, int N>
struct extract_type;

template<template<class ...> class C, class ...Ts, int N>
struct extract_type<C<Ts...>, N> {
  typedef typename extract_type_impl<N, Ts...>::type type;
};

template<int N, class T, class ...Ts>
struct extract_type_impl<N, T, Ts...> {
  typedef typename extract_type_impl<N - 1, Ts...>::type type;
};

template<class T, class ...Ts>
struct extract_type_impl<0, T, Ts...> {
  typedef T type;
};

int main() {
  static_assert(std::is_same<extract_type<C<int, float, char, double>, 3>::type, double>::value, "");
  // static_assert(std::is_same<extract_type<C<int, float, char, double>, 3>::type, int>::value, "");
}
  • 获取C
  • 的参数列表
  • 获取第n个参数

Live Demo