我不明白为什么以下失败:
#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 :(得分:1)
您可以部分地专门化类模板,但不能部分地专门化类模板的成员。而这恰恰是你尝试用pair
做的事情。
为什么以前的尝试不起作用:
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";