使用外部模板 (C++11)

using extern template (C++11)(使用外部模板 (C++11))
本文介绍了使用外部模板 (C++11)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

TemplHeader.h

TemplHeader.h

template<typename T>
void f();

TemplCpp.cpp

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;
}

这是使用 extern 模板 的正确方法,还是我只将这个关键字用于类模板,如图 2 所示?

Is this the correct way to use extern template, or do I use this keyword only for class templates as in Figure 2?

TemplHeader.h

TemplHeader.h

template<typename T>
class foo {
    T f();
};

TemplCpp.cpp

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;
}

我知道将所有这些放在一个头文件中是好的,但是如果我们在多个文件中实例化具有相同参数的模板,那么我们会得到多个相同的定义,编译器会将它们全部删除(一个除外)以避免错误.我如何使用 extern 模板?可以只用在类上,还是也可以用在函数上?

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?

此外,图 1 和图 2 可以扩展为模板位于单个头文件中的解决方案.在这种情况下,我们需要使用 extern template 关键字来避免多个相同的实例化.这是否也仅适用于类或函数?

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?

推荐答案

你应该只使用 extern template 强制编译器在 实例化模板您知道 它将在其他地方实例化.它用于减少编译时间和目标文件大小.

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 object file size.

例如:

// 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

如果两个文件链接在一起,一个voidReallyBigFunction()将被丢弃,导致浪费编译时间和目标文件大小.

If both files are linked together, one void ReallyBigFunction<int>() will be discarded, resulting in wasted compile time and object file size.

为了不浪费编译时间和目标文件大小,有一个 extern 关键字使编译器不编译模板函数.您应该使用这个当且仅当您知道它在其他地方的同一个二进制文件中使用.

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.

source2.cpp 更改为:

// source2.cpp

#include "header.h"
extern template void ReallyBigFunction<int>();
void something2()
{
    ReallyBigFunction<int>();
}

将产生以下目标文件:

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.

这应该只在一个项目中使用,就像当你多次使用像 vector 这样的模板时,你应该使用 extern 除了一个源文件.

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.

这篇关于使用外部模板 (C++11)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Could I ever want to access the address zero?(我可以想访问地址零吗?)
C++ Access derived class member from base class pointer(C++ 从基类指针访问派生类成员)
Weird Behaviour with const_cast(const_cast 的奇怪行为)
Are pointer variables just integers with some operators or are they quot;symbolicquot;?(指针变量只是带有某些运算符的整数还是“符号?)
Modifying a char *const string(修改 char *const 字符串)
Modifying a const int in C++(修改 C++ 中的 const int)