Mar*_*son 20 c++ templates c++11
C++ 03的显式模板的实例化定义和C++ 11的显式模板的实例化声明之间有什么区别?
我的意思是为什么实例化定义不足以阻止编译器为其他类型生成实现?下面的例子有什么问题:想象一下我将模板声明和定义分成两个单独的文件:
啊
#pragma once
template<typename T>
class A
{
public:
A(T t);
private:
T _t;
};
Run Code Online (Sandbox Code Playgroud)
A.cpp
#include "A.h"
template<typename T>
A<T>::A(T t) : _t(t) {}
template class A<int>; // explicit instantiation
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "A.h"
int main()
{
A<int> a(5); // fine, compiler generates header file,
// linker links with implementation from A.cpp file
// A<float> b(3.14f); // linker error, as expected
}
Run Code Online (Sandbox Code Playgroud)
上面的示例中是否有任何编译时间开销?如果我理解正确,在这种情况下,在单独的*.cpp文件中使用显式实例化定义(以及模板的实现),我使编译器无法使用任何其他类型隐式实例化模板.因此,为什么显式实例化声明有单独的语法?
如果我已经使用显式实例化定义隐藏了A.cpp文件中的实现,并且阻止编译器为其他类型生成主体,那么显式实例化声明如何加快编译时间."显式实例化声明"是否与"显式实例化定义"有某种关联,我的意思是我应该同时使用它们,还是这些是完全独立的特性(例如,只有在未使用显式实例化定义时才能使用显式实例化声明)?
我是否正确,明确的实例化定义只是在没有其他翻译单元使用给定类型实例化模板的情况下触发错误?
Jon*_*ely 28
当你在文件中放置一个显式的实例化定义时A.cpp
,编译器在编译时应该如何知道它main.cpp
?答案是它不能,所以它仍然会实例化所使用的模板main.cpp
,在你的情况下使用显式实例化定义是没用的,并没有帮助.
显式实例化的声明告诉编译器"不要打扰实例化这个模板,我将自己,在程序中的其他地方",并且定义是履行该承诺的.
显式实例化必须只在一个文件中定义一次,但可以在不同的文件中多次声明.这对于模板来说并不是唯一的,在C和C++中,相同的规则适用于(非内联)函数:您可以在不同的文件中多次声明它们(通常通过将声明放在标题中)然后您必须准确定义函数一次,在一个文件中.
因此,为了使您的示例正常工作,您应该在A.h
以下位置添加声明:
extern template class A<int>; // explicit instantiation declaration
Run Code Online (Sandbox Code Playgroud)