模板类成员专业化声明

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模板常见问题.