我正在为任何模板化类实现类型提取器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;
我如何解决这个问题?
答案 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, "");
}