Когда я специализирую (статическую) функцию-член/константу в классе шаблона, я смущен относительно того, куда должно идти объявление.
Вот пример того, что мне делать, - прямо из ссылка 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
}
Вопрос в том, как я могу разделить это на файлы header/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; }
... но я понятия не имею, правильно ли это. Любые идеи?