使用extern模板(C ++ 11) [英] using extern template (C++11)

查看:234
本文介绍了使用extern模板(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆