使用extern模板(C ++ 11) [英] using extern template (C++11)
问题描述
图1:函数模板
TemplHeader.h
template< typename T>
void f();
TemplCpp.cpp
template< typename T>
void f(){
// ...
}
//显式实例化
template void f< T&
Main.cpp
#includeTemplHeader.h
extern template void f< T>(); //它是否正确?
int main(){
f< char>();
return 0;这是正确的使用方法 extern template <$ c
,或者我是否只对类模板使用此关键字,如图2所示?
图2: / h2>
TemplHeader.h
template< typename T>
class foo {
T f();
};
TemplCpp.cpp
template< typename T>
void foo< T> :: f(){
// ...
}
//显式实例化
模板类foo< int>
Main.cpp
#includeTemplHeader.h
extern template class foo< int>();
int main(){
foo< int>测试;
return 0;
}
我知道将所有这一切放在一个头文件如果我们在多个文件中实例化具有相同参数的模板,那么我们得到了多个相同的定义,编译器会删除它们(除了一个),以避免错误。如何使用 extern template
?
此外,图1和图2可以扩展到一个解决方案,其中模板是在一个单个头文件。在这种情况下,我们需要使用 extern template
关键字来避免多个相同的实例。
解决方案你应该只使用 extern template
强制编译器在 确认将在其他地方实例化时,不会实例化模板。它用于减少编译时间和减少对象文件大小。
例如:
code> // header.h
template< typename T>
void ReallyBigFunction()
{
// Body
}
// source1.cpp
#includeheader .h
void something1()
{
ReallyBigFunction< int>();
}
// source2.cpp
#includeheader.h
void something2()
{
ReallyBigFunction< int>();
}
这将产生以下目标文件:
source1.o
void something1()
void ReallyBigFunction< int>()//第一次编译
source2.o
void something2()
void ReallyBigFunction< int>()//第二次编译
$ b b
如果两个文件都链接在一起,一个 void ReallyBigFunction< int>()
将被丢弃,导致浪费编译时间和对象文件大小。
为了不浪费编译时间和对象文件大小,有一个 extern
关键字,模板功能。
更改 source2时,您应该使用此 .cpp
至:
// source2.cpp
#include header.h
extern template ReallyBigFunction< int>();
void something2()
{
ReallyBigFunction< int>();
}
将产生以下对象文件:
source1.o
void something1()
void ReallyBigFunction< int>()//只编译一次
source2.o
void something2()
//没有ReallyBigFunction< int>这里因为extern
当这两个都链接在一起时,第二个目标文件将只使用来自第一个目标文件的符号。不需要丢弃,也不浪费编译时间和对象文件大小。
这应该只在项目中使用,就像在使用向量< int>
多次,您应该在除了一个源文件之外的所有文件中使用 extern
。
这也适用于类和函数作为一个,甚至模板成员函数。
Figure 1: function templates
TemplHeader.h
template<typename T>
void f();
TemplCpp.cpp
template<typename T>
void f(){
//...
}
//explicit instantation
template void f<T>();
Main.cpp
#include "TemplHeader.h"
extern template void f<T>(); //is this correct?
int main() {
f<char>();
return 0;
}
Is this the correct way to use extern template
, or do I use this keyword only for class templates as in Figure 2?
Figure 2: class templates
TemplHeader.h
template<typename T>
class foo {
T f();
};
TemplCpp.cpp
template<typename T>
void foo<T>::f() {
//...
}
//explicit instantation
template class foo<int>;
Main.cpp
#include "TemplHeader.h"
extern template class foo<int>();
int main() {
foo<int> test;
return 0;
}
I know it is good to put all of this in one header file, but if we instantiate templates with the same parameters in multiple files, then we got multiple same definitions and the compiler will remove them all (except one) to avoid errors. How do I use extern template
? Can we use it only for classes, or can we use it for functions too?
Also, Figure 1 and Figure 2 may be expanded to a solution where templates are in a single header file . In that case, we need to use the extern template
keyword to avoid multiple same instantations. Is this only for classes or functions too?
You should only use extern template
to force the compiler to not instantiate a template when you know that it will be instantiated somewhere else. It is used to reduce compile time and reduce object file size.
For example:
// header.h
template<typename T>
void ReallyBigFunction()
{
// Body
}
// source1.cpp
#include "header.h"
void something1()
{
ReallyBigFunction<int>();
}
// source2.cpp
#include "header.h"
void something2()
{
ReallyBigFunction<int>();
}
This will result in the following object files:
source1.o
void something1()
void ReallyBigFunction<int>() // Compiled first time
source2.o
void something2()
void ReallyBigFunction<int>() // Compiled second time
If both files are linked together, one void ReallyBigFunction<int>()
will be discarded, resulting in wasted compile time and object file size.
To not waste compile time and object file size, there is an extern
keyword which makes the compiler not compile a template function. You should use this if and only if you know it is used in the same binary somewhere else.
Changing source2.cpp
to:
// source2.cpp
#include "header.h"
extern template ReallyBigFunction<int>();
void something2()
{
ReallyBigFunction<int>();
}
Will result in the following object files:
source1.o
void something1()
void ReallyBigFunction<int>() // compiled just one time
source2.o
void something2()
// No ReallyBigFunction<int> here because of the extern
When both of these will be linked together, the second object file will just use the symbol from the first object file. No need for discard and no wasted compile time and object file size.
This should only be used within a project, like in times when you use a template like vector<int>
multiple times, you should use extern
in all but one source file.
This also applies to classes and function as one, and even template member functions.
这篇关于使用extern模板(C ++ 11)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!