如何专门用于模板模板参数

How to specialize for template template arguments

本文关键字:参数 用于 何专门      更新时间:2023-10-16

我想使用模板类型来专业化功能,但是我很难获得所需的结果。

考虑以下简单示例

#include <iostream>
#include <typeinfo>
#include <vector>

template <typename T>
void foo(){
    std::cout << "In foo1 with type: " << typeid(T).name() << std::endl;
}
template< template<class, class...> class VEC, typename T>
void foo(){
    std::cout << "In foo2 with vec type: " << typeid(VEC<T>).name()
              << " and template type: " << typeid(T).name() << std::endl;
}

int main() {
    foo<int>();
    foo<std::vector, int>();
    foo<std::vector<int>>(); // Would like this to call the second version of foo
}

其输出为

In foo1 with type: i
In foo2 with vec type: St6vectorIiSaIiEE and template type: i
In foo1 with type: St6vectorIiSaIiEE

有没有办法为第二版的FOO编写模板签名,该签名将用于Foo的最后一次调用(带有STD :: vector模板参数)?

谢谢!

由于您无法部分地专业化函数模板,因此通常的方法是使用助手类模板:

template <typename T> struct X
{
    static void f() { std::cout << "Primaryn"; }
};
template <template <typename...> class Tmpl, typename T>
struct X<Tmpl<T>>
{
    static void f() { std::cout << "Specializedn"; }
};
template <typename T> void foo() { X<T>::f(); }

替代方案是标签派遣:

template <typename> struct Tag{};
template <typename T> void foo(Tag<T>) { std::cout << "genericn"; }
template <typename T> void foo(Tag<std::vector<T>>) { std::cout << "vectorn"; }

template <typename T> void foo()
{
    foo(Tag<T>{});
}