[英]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, "");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.