如何获取模板模板参数的模板参数?

8
假设std::vector没有value_type,那么能否编写一个模板来推断value_type?或者更一般地说,给定一个T<X>,如何推断出X
非常幼稚的方法是...
template <template <typename X> T>
void test(T<X> t) { 
     X x;
}

我猜任何对模板有一些了解的人看到这个代码都会嘲笑我的愚蠢尝试,当像这样实例化时:

int main() {
    std::vector<int> x;
    test(x);
}

创建以下错误:
error: expected ‘classbeforeTtemplate < template<typename X> T>
                                 ^
error: ‘Xwas not declared in this scope
 void test(T<X> u) {
             ^
error: template argument 1 is invalid
 void test(T<X> u) {
              ^
In functionvoid test(int)’:
error: ‘Xwas not declared in this scope
   X x;
   ^
error: expected ‘;’ before ‘x’
   X x;
     ^
In functionint main()’:
error: no matching function for call totest(std::vector<int>&)’
   test(x);
         ^
note: candidate is:
note: template<template<class X> class T> void test(int)
 void test(T<X> u) {
      ^
note:   template argument deduction/substitution failed:
note:   cannot convert ‘x’ (type ‘std::vector<int>’) to type ‘int

编辑:第一个问题很容易解决,但修复它不会影响其他问题...

PS:我认为我有一个小误解,因为std::vector<int>不是一个模板,而是一个具体类型。然而,我仍然想知道是否有一种方法可以使用一些模板魔法从someTemplate<int>中获取int


如果我没记错的话,你必须在嵌套模板中使用 class。类似这样:template <template <typename X> class T> - pingul
1
请注意,std::vector 有第二个(默认)模板参数。 - Jarod42
有点绕,但如果你只是在处理容器,你可以获取一个迭代器并使用std::iterator_traits - NathanOliver
1个回答

9
您可以创建一个特性来提取这些参数:
template <typename T> struct first_param;

template <template <typename, typename...> class C, typename T, typename ...Ts>
struct first_param<C<T, Ts...>>
{
    using type = T;
};

在 C++11 之前,你必须处理参数数量直到接受的值:

template <typename T> struct first_param;

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

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

template <template <typename, typename, typename> class C,
          typename T, typename T2, typename T3>
struct first_param<C<T, T2, T3>>
{
    typedef T type;
};

// ...

看起来像是C++11或以上版本,如果我在问题中没有表述清楚,对不起。 - 463035818_is_not_a_number
@tobi303:添加了C++03版本。 - Jarod42
我很幸运,我要寻找的具体情况只有一个参数。感谢您的答复。看到所有这些 ...using 我担心 C++03 的解决方案会是可怕的黑客行为,但那个解决方案看起来相当好和容易。 - 463035818_is_not_a_number
刚刚在这个问题上收到了一条提醒,很惊讶自己以前知道的那么少。我知道这有点跑题,但我认为在这里大声说一声“谢谢!”是非常合适的,感谢在我在 SO 上学习 C++ 期间得到的所有帮助。 - 463035818_is_not_a_number

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接