模板类的模板特化

时间:2014-01-09 20:46:02

标签: c++ templates

我一直在寻找关于模板专业化的许多其他问题,而我似乎无法找到问题的答案。我已经读过你不能部分专门化功能模板。那么接下来的工作是什么呢。

考虑一个名为type的函数。此函数用于返回表示其类型的单个char。在构建类时,您必须“重载”或专门化函数type,以便名为print_type的函数可以打印对象的类型,而无需调用函数type 。这是一些代码:

#include <cstdio>
#include <string>
#include <vector>

template<class T> inline char type(const T&) {return 'S';}
template<> inline char type(const int&) {return 'I';}
template<> inline char type(const double&) {return 'R';}

template<class T>
void print_type(T& t) {
    printf("Type = %c\n", type(t));
}

// OTHER FUTURE TYPES
template<> inline char type(const std::string&) {return 'W';}
template<class T> inline char type(const std::vector<T>&) {return 'T';}

int main() {
    int x;
    printf("Int type: %c\n", type(x));
    print_type(x);

    double y;
    printf("Double type: %c\n", type(y));
    print_type(y);

    std::string str;
    printf("String type: %c\n", type(str));
    print_type(str);

    std::vector<int> vtor;
    printf("Vector type: %c\n", type(vtor));
    print_type(vtor);
}

请注意,我已为type定义了专门的std::string。不知何故,似乎无法对某些类型std::vector<T>的{​​{1}}进行处理。运行上面代码的结果给出了:

T

macbook-pro:~ jmlopez$ ./a.out Int type: I Type = I Double type: R Type = R String type: W Type = W Vector type: T Type = S 函数无法获取print_type的定义,它只是默认为我定义的原始模板函数。这将是一个什么样的解决方案?请记住,我必须能够在某些可能的未来为其他未知类型定义std::vector<std::string>,因此在设置了type的所有定义后,我无法声明函数print_type

1 个答案:

答案 0 :(得分:2)

无法部分专门化功能模板的规范解决方法是委托部分专用的类模板,可能具有合适的static成员函数。例如:

template <typename> struct type_aux { static char type() { return 'S'; } };
template <> struct type_aux<int> { static char type() { return 'I'; } };
template <> struct type_aux<double> { static char type() { return 'R'; } };
template <> struct type_aux<std::string> { static char type() { return 'W'; } };
template <typename T> struct type_aux<std::vector<T>> {
    static char type() { return 'T'; }
}

template <typename T> char type(T const&) { return type_aux<T>::type(); }

只是为了解释为什么你的方法不能像你编写它一样工作:在template <typename T> char type(std::vector<T> const&)的实例化过程中需要找到函数模板print_type()。但是,此时只能通过参数依赖查找找到函数,这些查找不会查找您定义它的位置。如果您在namespace std中声明了功能模板,则可以创建功能模板但不允许这样做。专业化方法完全侧重于必须定位函数的问题。