繁体   English   中英

从模板化类中提取类型

[英]Extract a type from a templated class

我正在为任何模板化类实现类型提取器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... > { 
};

但是,编译器抱怨

模板参数C的模板参数列表中参数1处的类型/值不匹配,模板类C,长无符号int idx,类T,类... RestT> struct OpenCluster :: extract_type'struct extract_type <void,0,RestT ...>

我怎样才能解决这个问题?

您是说类似的意思(最小的工作示例)吗?

#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

结果相同: double

在你的例子中得到了错误(当然,除了语法之外)?

这是我的实施。

#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个参数

现场演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM