我有一个类模板 name
来检测类型名称。它适用于简单类型,例如 int
、float
。但是,对于某些模板类型,如 std:pair
,当我尝试定义其静态成员变量时,编译器 (VS2013) 会在该行报告错误。
#include <cassert>
#include <memory>
using namespace std;
template<class T> struct name{ static const char* value; };
template<class T> const char* name<T>::value = "unknown";
template<> const char* name<int>::value = "int";
template<> const char* name<float>::value = "float";
template<class T1, class T2> const char* name<pair<T1, T2> >::value = "pair"; //compilation error
void main()
{
assert(name<int>::value == "int");
assert(name<float>::value == "float");
assert(name<double>::value == "unknown");
assert((name<pair<int, char> >::value) == "pair");
}
如果我用以下四行替换该行,程序将按预期工作。
template<class T1, class T2> struct name < pair<T1, T2> > {
static const char* value;
};
template<class T1, class T2> const char* name<pair<T1, T2> >::value = "pair";
但是由于一些重复的代码,这种方式看起来很难看。有什么办法可以走走吗?
已更新以修复一些明显的标准合规性问题。
最佳答案
首先:template<>
必须引入任何显式特化.尽量保持符合标准。
But this way looks ugly due to some duplicate code. Is there any way to walk around?
没有。非显式特化的成员定义中的参数和实参列表必须匹配主模板或其部分特化之一的列表,并且它对应于其列表匹配的模板成员。 [temp.class.spec.mfunc]:
The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization. The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization.
所以你必须部分特化模板。不过,您可以为此使用宏:
#define REM_PAR(...) __VA_ARGS__
#define PART_SPEC(string, params, ...) \
template<REM_PAR params> struct name <__VA_ARGS__ > \
{ static const char* value; }; \
\
template<REM_PAR params> const char* name<__VA_ARGS__>::value = string;
PART_SPEC("pair", (class T, class U), pair<T,U>)
关于c++ - 类模板特化与模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26440493/