当前位置: 首页 > 知识库问答 >
问题:

从模板化类中提取类型

贺自明
2023-03-14

我正在为任何模板化的类实现一个类型提取器extract_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个答案

何睿范
2023-03-14

你的意思是类似的(最小的,工作的例子)吗?

#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;
}

很丑,不是吗?

template <size_t idx, typename T, typename... RestT> 
struct extract_type;
extract_type<1, int, double, char>::type

结果相同:double

在您的示例中发现了错误(当然,除了语法错误)?

 类似资料:
  • 关于下一个代码,我有一些问题: > 类专业化

  • 还尝试在专门化的中进行模板方法专门化: 这一次它编译,但调用原始方法,即 解决方案

  • 我有以下问题:一个类模板a,有几个模板参数,我想构建一个类B,它以a为模板参数,并提取a的第一个模板参数,以便在某种方法中使用它(想想从std::vector 中提取int并返回默认的int{})。 我知道这种天真的方法不会编译,但我不知道如何实现这样的东西。感谢任何提示。

  • 我需要声明一个可以存储不同类型容器的类。也就是说,如果它能处理STD::Bitset和STD::Array就好了。但是,这两个类需要不同的模板参数······是否可能(以及如何)使用模板化模板类和可变模板来声明此类类? 示例(但错误):

  • 我有一个类游戏面板方法更新()。如何将该方法提取到单独的文件(类)? 我尝试进行类更新:

  • 我试图做到以下几点:一个模板化的类应该提供一些函数,这些函数取决于它模板化的类型是否包含一个具有给定名称的成员变量。作为示例,下面的伪代码应该只在模板化的结构/类具有名为“id”的成员时才提供“printId()”: 通过研究SFINAE,traits,std::enable_if和StackOverflow,我认为这是可以做到的...但是我不知为什么没有将enable_if与以下问题中的片段结合