获取模板类型的模板参数类型

Getting at template parameter types of a template type

本文关键字:类型 参数 获取      更新时间:2023-10-16

我有一个关于模板的问题,它在代码中:

template<typename T>
struct foo {
  T t;
};
template<typename FooType>
struct bar {
  T t; //<- how to get T here (preferably without using typedef in foo)
};

这是一个通用的模板参数类型提取器:

#include <tuple>
template <typename> struct tuplify;
template <template <typename...> class Tpl, typename ...Args>
struct tuplify<Tpl<Args...>>
{
    using type = std::tuple<Args...>;
};
template <typename T, unsigned int N>
using get_template_argument
    = typename std::tuple_element<N, typename tuplify<T>::type>::type;

用法:

get_template_argument<std::vector<int>, 1> a;  // is a std::allocator<int>

或者在你的情况下:

get_template_argument<FooType, 0> t;

如果我正确理解了你的问题,你可以像下面这样使用模板专门化。给定foo<>类模板:

template<typename T>
struct foo {
  T t;
};

定义bar<>主模板和相应的专门化:

template<typename FooType>
struct bar;
template<typename T>
struct bar<foo<T>> {
  T t; // T will be int if the template argument is foo<int>
};

假设您总是应该通过提供foo<>的实例作为类型参数来实例化bar,您可以不定义主模板。

专门化将匹配foo<T>模式,从而给出在T中实例化foo<>的类型。

下面是如何用一个简单的程序测试这种方法的有效性:
#include <type_traits>
int main()
{
    bar<foo<int>> b;
    // This will not fire, proving T was correctly deduced to be int
    static_assert(std::is_same<decltype(b.t), int>::value, "!");
}

下面是相应的实例

如果您不想或不能为foo添加typedef,您可以另外编写一个独立的"extractor"模板

template <typename T> struct ExtractT;
template <typename T> struct ExtractT<foo<T> > {
  typedef T type;
};

作为

template<typename FooType>
struct bar {
  typename ExtractT<FooType>::type t;
}; 

你可以进一步将ExtractTfoo解耦

template <typename T> struct ExtractT;
template <template <typename> class C, typename T> struct ExtractT<C<T> > {
  typedef T type;
};

等等,直到您从Boost或c++ 11标准库中重新发明一些东西:)顺便说一句,这感觉应该已经以更通用的解决方案的形式可用....