当我在模板类中专门化一个(静态)成员函数/常量时,我对声明的去向感到困惑。
这是我要做什么的一个例子 - 直接来自IBM 关于模板专业化的参考 http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/explicit_specialization.htm#explicit_specialization:
===IBM 会员专业化示例===
template<class T> class X {
public:
static T v;
static void f(T);
};
template<class T> T X<T>::v = 0;
template<class T> void X<T>::f(T arg) { v = arg; }
template<> char* X<char*>::v = "Hello";
template<> void X<float>::f(float arg) { v = arg * 2; }
int main() {
X<char*> a, b;
X<float> c;
c.f(10); // X<float>::v now set to 20
}
问题是,如何将其分为头文件/cpp 文件?通用实现显然在标头中,但是专业化呢?
它不能放在头文件中,因为它是具体的,导致多个定义。但是,如果它进入 .cpp 文件,调用 X::f() 的代码是否知道专门化,或者它可能依赖于通用 X::f() ?
到目前为止,我仅在 .cpp 中进行了专门化,标头中没有声明。我在编译甚至运行我的代码时都没有遇到问题(在 gcc 上,目前不记得版本),并且它的行为符合预期 - 识别专业化。但是 A) 我不确定这是正确的,我想知道正确的是什么,B) 我的 Doxygen 文档很不稳定并且非常具有误导性(稍后将在 a moment 中详细介绍)问题)。
对我来说最自然的是这样的,在标头中声明专业化并在 .cpp 中定义它:
===XClass.hpp===
#ifndef XCLASS_HPP
#define XCLASS_HPP
template<class T> class X {
public:
static T v;
static void f(T);
};
template<class T> T X<T>::v = 0;
template<class T> void X<T>::f(T arg) { v = arg; }
/* declaration of specialized functions */
template<> char* X<char*>::v;
template<> void X<float>::f(float arg);
#endif
===XClass.cpp===
#include <XClass.hpp>
/* concrete implementation of specialized functions */
template<> char* X<char*>::v = "Hello";
template<> void X<float>::f(float arg) { v = arg * 2; }
……但我不知道这是否正确。有任何想法吗?