顯式例項化
顯式例項化定義從模板建立並宣告具體的類,函式或變數,而不使用它。可以從其他翻譯單元引用顯式例項化。這可用於避免在標頭檔案中定義模板,如果它僅使用有限的引數集進行例項化。例如:
// print_string.h
template <class T>
void print_string(const T* str);
// print_string.cpp
#include "print_string.h"
template void print_string(const char*);
template void print_string(const wchar_t*);
因為 print_string<char>
和 print_string<wchar_t>
是在 print_string.cpp
中顯式例項化的,所以即使未在標頭檔案中定義 print_string
模板,連結器也能夠找到它們。如果不存在這些顯式例項化宣告,則可能會發生連結器錯誤。請參閱為什麼模板只能在標頭檔案中實現?
Version >= C++ 11
如果顯式例項化定義前面是 extern
關鍵字 ,則它將成為顯式例項化宣告。給定特化的顯式例項化宣告的存在阻止了當前轉換單元內給定特化的隱式例項化。相反,對該特化的引用否則將導致隱式例項化可以引用相同或另一個 TU 中的顯式例項化定義。
foo.h
#ifndef FOO_H
#define FOO_H
template <class T> void foo(T x) {
// complicated implementation
}
#endif
foo.cpp
#include "foo.h"
// explicit instantiation definitions for common cases
template void foo(int);
template void foo(double);
main.cpp
#include "foo.h"
// we already know foo.cpp has explicit instantiation definitions for these
extern template void foo(double);
int main() {
foo(42); // instantiates foo<int> here;
// wasteful since foo.cpp provides an explicit instantiation already!
foo(3.14); // does not instantiate foo<double> here;
// uses instantiation of foo<double> in foo.cpp instead
}