2014-10-18 65 views
1

我不明白为什么以下故障:模板偏特将无法正常工作

#include <cassert> 
#include <memory> 
#include <utility> 

using namespace std; 

template<typename... T> struct name{ static const char* value; }; 

template<typename... T> const char* name<T...>::value = "unknown"; 
template <> const char* name<int>::value = "int"; 
template <> const char* name<float>::value = "float"; 
template <> const char* name<template<typename,typename> class T>::value = "pair"; 

int main() 
{ 
    assert(name<int>::value == "int"); 
    assert(name<float>::value == "float"); 
    assert(name<double>::value == "unknown"); 
    assert((name<pair<int, char> >::value) == "pair"); 
} 

问题是在该行

template <> const char* name<template<typename,typename> class T>::value = "pair"; 

[temp.class.spec.mfunc]应定义这种行为,但阅读标准后,我仍然不明白。有人能解释我吗(用最清晰简洁的方式)为什么这些工作都不起作用?

template <> const char* name<template<typename,typename> class T>::value = "pair"; 
template <typename T1, typename T2> const char* name<std::pair<T1,T2>>::value = "pair"; 
+0

http://stackoverflow.com/questions/26440493/template-class-specialization-with-template似乎是相同的分配,你可能会感兴趣的答案有 – Mat 2014-10-18 14:39:41

+0

我首先不理解这个答案 – Dean 2014-10-18 14:40:05

+0

1.你不能部分地专门化类的成员,2.你使用无效的语法来部分专用于双参数类模板 – 2014-10-18 14:46:12

回答

1

可以部分专业类模板,但你不能偏特一成员的类模板。这正是你想要做的事情pair事情。

为什么preceisely的尝试不起作用:

template <> const char* name<template<typename,typename> class T>::value = "pair"; 

一个明确的专业化(即,不是局部特殊化)是不是一个模板。它的前缀为template <>,完全专用模板名称必须为所有模板参数指定参数。所以,你可以为这个例子做:

template <> const char* name<std::pair<int, double>>::value = "pair"; 

但是你原来的代码是语法废话 - 如果有的话,它看起来就像是试图声明模板参数列表内的两个参数的类模板T

至于第二行:

template <typename T1, typename T2> const char* name<std::pair<T1,T2>>::value = "pair"; 

这是部分特正确的语法。不幸的是,正如我上面所说,你不能部分地专门化类模板成员,只有整个类模板。所以,你必须这样做:

template <typename T1, typename T2> struct name<std::pair<T1,T2>> 
{ 
    static const char* value; 
}; 

template <typename T1, typename T2> const char* name<std::pair<T1,T2>>::value = "pair"; 
+0

谢谢,这是一个很好的解释。 – Dean 2014-10-18 15:23:37