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

时间:2013-06-08 15:49:04

标签: c++ templates

我对模板有疑问,它在代码中:

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

3 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

如果我正确理解了您的问题,您可以使用模板专业化,如下所示。鉴于您的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>
};

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

专精化将与foo<T>模式匹配,从而为您提供foo<>T实例化的类型。

以下是使用简单程序测试此方法的有效性的方法:

#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, "!");
}

以下是相应的live example

答案 2 :(得分:1)

如果您不想或不能将typedef添加到foo,您还可以另外编写一个独立的“提取器”模板

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

您可以更进一步ExtractT并将其与foo

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

等等,直到你重新发明Boost或C ++ 11标准库中的东西:)顺便说一句,这感觉就像是应该已经以更通用的解决方案形式提供的东西......