请参阅以下代码,请清除我的疑虑.
由于ABC是一个模板,为什么当我们在test.cpp中放置ABC类成员函数的定义时它不显示错误?
如果我在test.h和remve 2中放入test.cpp代码,那么它可以正常工作.为什么?
.
// test.h
template <typename T>
class ABC {
public:
void foo( T& );
void bar( T& );
};
// test.cpp
template <typename T>
void ABC<T>::foo( T& ) {} // definition
template <typename T>
void ABC<T>::bar( T& ) {} // definition
template void ABC<char>::foo( char & ); // 1
template class ABC<char>; // 2
// main.cpp
#include "test.h"
int main() {
ABC<char> a;
a.foo(); // valid with 1 or 2
a.bar(); // link error if only 1, valid with 2
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*eas 13
在这两种情况下,您都在进行显式实例化.在第二种情况下,仅ABC<char>::foo实例化,而在第一种情况下ABC<char>::bar也被实例化.
一个不同的类似例子可以澄清其含义:
// test.h
template <typename T>
class ABC {
public:
void foo( T& );
void bar( T& );
};
// test.cpp
template <typename T>
void ABC<T>::foo( T& ) {} // definition
template <typename T>
void ABC<T>::bar( T& ) {} // definition
template void ABC<char>::foo( char & ); // 1
template class ABC<char>; // 2
// main.cpp
#include "test.h"
int main() {
ABC<char> a;
a.foo(); // valid with 1 or 2
a.bar(); // link error if only 1, valid with 2
}
Run Code Online (Sandbox Code Playgroud)
在示例中,在main编译器中看不到foo也没有bar定义,因此无法实例化方法.处理main.cpp时,编译器会很乐意接受main中的代码,因为你告诉它ABC是一个模板并且它有这两个函数,并假设它们将在其他一些翻译单元中定义.
在包含test.cpp的转换单元中,编译器会看到两个方法定义,并且可以完全处理这两个实例(方法/类).如果仅存在方法实例化([1]),则编译器将仅生成该方法,并将保留bar未定义.因此,任何包含test.h的代码,针对已编译的test.cpp的链接以及仅使用foo方法都将进行编译和链接,但bar由于未定义,因此无法使用链接.
显式实例化类模板会为所有成员方法生成符号,在这种情况下,任何包含test.h的翻译单元和编译的test.cpp对象文件的链接都将编译和链接.
| 归档时间: |
|
| 查看次数: |
693 次 |
| 最近记录: |