Dej*_*vić 5 c++ templates explicit
说我声明一个模板类A中a.h
#include <iostream>
template<bool b>
class A {
public:
void print(std::ostream& out);
};
Run Code Online (Sandbox Code Playgroud)
并确定在打印方法a.cpp(与明确的instatiation true和false)
#include "a.h"
template<bool b>
void A<b>::print(std::ostream& out) {
out << "A" << b;
}
template class A<true>;
template class A<false>;
Run Code Online (Sandbox Code Playgroud)
main.cpp可以是一个主要的主要程序示例
#include "a.h"
int main() {
A<true> a;
a.print(std::cout);
}
Run Code Online (Sandbox Code Playgroud)
上面的小项目编译得很好.
问题:如果我将显式实例化放在print方法(in a.cpp)的定义之上,则代码不再编译,并且通常会undefined reference to A<true>::print(...)出现错误.
#include "a.h"
template class A<true>;
template class A<false>;
template<bool b>
void A<b>::print(std::ostream& out) {
out << "A" << b;
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
编辑:Makefile进行编译
main : main.o a.o
g++ main.o a.o -o main
main.o : main.cpp
g++ -c main.cpp
a.o : a.cpp
g++ -c a.cpp
Run Code Online (Sandbox Code Playgroud)
我认为没有一个很好的自然解释为什么会这样.显然,编译器可以看到成员函数的定义,即使它是在显式实例化之后提供的 - 因为它位于同一个文件中.
但是,编译器不需要这样做; 事实上,标准明确禁止:
(§14.7.2/ 9)命名类模板特化的显式实例化定义显式实例化类模板特化,并且是仅在实例化时定义的那些成员的显式实例化定义.
我猜其原因包括:
对于稍后在翻译单元中的某些成员函数,可能存在若干不同的显式特化; 同样符合程序员的利益,有一个关于哪些将被实例化的明确规则是有道理的;
当隐式实例化模板时,仅考虑在实例化之前定义的特化; 所以隐式和显式实例化的规则是相同的.