0

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

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

3 回答 3

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;
于 2013-06-08T16:15:52.410 回答
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, "!");
}

这是相应的现场示例

于 2013-06-08T15:53:47.293 回答
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 标准库中重新发明一些东西:) 顺便说一句,这感觉就像应该已经以更通用的解决方案的形式提供的东西......

于 2013-06-08T15:57:42.800 回答