Ziv*_*Ziv 14 c++ templates declaration template-specialization
当我在模板类中专门化(静态)成员函数/常量时,我对于声明的去向感到困惑.
以下是我该做什么的一个例子 - 直接从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
}
Run Code Online (Sandbox Code Playgroud)
问题是,如何将其分为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
Run Code Online (Sandbox Code Playgroud)
=== 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; }
Run Code Online (Sandbox Code Playgroud)
......但我不知道这是否正确.有任何想法吗?
Geo*_*che 11
通常你只是inline在dirkgently中定义标题中的特化.
如果您担心编译时间或代码膨胀,您可以在单独的翻译单元中定义特化:
// x.h:
template<class T> struct X {
void f() {}
}
// declare specialization X<int>::f() to exist somewhere:
template<> void X<int>::f();
Run Code Online (Sandbox Code Playgroud)
// translation unit with definition for X<int>::f():
#include "x.h"
template<> void X<int>::f() {
// ...
}
Run Code Online (Sandbox Code Playgroud)
所以是的,你的方法看起来很好.请注意,您只能使用完全特化来执行此操作,因此执行此操作通常是不切实际的.
有关详细信息,请参阅例如Comeaus模板常见问题.