我有一个模板类,我在标头中声明了一个方法,并且在标头中没有定义该方法。在 .cc 文件中,我定义了该方法的特化,而从未在 header 中声明它们。在不同的 .cc 文件中,我为存在特化的不同模板参数调用该方法。它看起来像这样:
富.h:
template<typename T>
class Foo {
public:
static int bar();
};
foo.cc:
#include "foo.h"
template<>
int Foo<int>::bar() {
return 1;
}
template<>
int Foo<double>::bar() {
return 2;
}
主.cc:
#include <iostream>
#include "foo.h"
int main(int argc, char **argv) {
std::cout << Foo<int>::bar() << std::endl;
std::cout << Foo<double>::bar() << std::endl;
return 0;
}
对于所有 C++ 标准(c++98、gnu++98、c++11 和 gnu++11),该程序可以成功地与 gcc 4.7.2 进行编译和链接。输出是:
1
2
这对我来说很有意义。因为 main.cc 翻译单元看不到它的定义bar()
或任何特化,它期望调用使用在某些其他翻译单元bar()
中的非特化定义的显式实例化。bar()
但是由于名称修改是可预测的,因此 foo.cc 中的特化具有与非特化定义的显式实例化相同的符号名称,因此 main.cc 能够使用这些特化而无需在该翻译单元中声明它们。
我的问题是:这是一个意外,还是 C++ 标准规定的这种行为?换句话说,这段代码是否可移植?
我能找到的最相关的先前问题是Declaration of template class member specialization,但它不包括这种特殊情况。
(如果你想知道为什么这对我很重要,那是因为我使用这样的代码作为一种编译时查找表,如果我不声明专业化,它会短得多。)