テンプレート クラスで (静的) メンバー関数/定数を特殊化すると、宣言がどこに行くべきかについて混乱します。
これは私が何をすべきかの例です -テンプレートの特殊化に関するIBMのリファレンスから直接引用しました:
===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のドキュメントが不安定で非常に誤解を招くようになっています(これについては、後で質問します)。
私にとって最も自然に思えるのは、次のようなもので、ヘッダーで特殊化を宣言し、.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; }
...しかし、これが正しいかどうかはわかりません。何か案は?