我知道在最初的C++0x标准中有一种名为export
的功能。
但我找不到关于这个功能的描述或解释。它应该是用来做什么的?另外,哪个编译器支持它?
我知道在最初的C++0x标准中有一种名为export
的功能。
但我找不到关于这个功能的描述或解释。它应该是用来做什么的?另外,哪个编译器支持它?
虽然标准C++没有这样的要求,但是一些编译器要求所有函数模板在使用的每个翻译单元中都需要可用。实际上,对于这些编译器,模板函数的主体必须在头文件中可用。需要重申的是:这意味着这些编译器不允许它们在非头文件(例如.cpp文件)中定义。换句话说,在C++中,这意味着:
// ORIGINAL version of xyz.h
template <typename T>
struct xyz
{
xyz();
~xyz();
};
以下这些构造函数和析构函数的定义可能无法满足要求:
// ORIGINAL version of xyz.cpp
#include "xyz.h"
template <typename T>
xyz<T>::xyz() {}
template <typename T>
xyz<T>::~xyz() {}
因为使用它:
// main.cpp
#include "xyz.h"
int main()
{
xyz<int> xyzint;
return 0;
}
代码将会产生一个错误。例如,使用Comeau C++编译器,您会得到以下错误信息:
C:\export>como xyz.cpp main.cpp
C++'ing xyz.cpp...
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:non-strict warnings microsoft C++
C++'ing main.cpp...
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing. All rights reserved.
MODE:non-strict warnings microsoft C++
main.obj : error LNK2001: unresolved external symbol xyz<T1>::~xyz<int>() [with T1=int]
main.obj : error LNK2019: unresolved external symbol xyz<T1>::xyz<int>() [with T1=int] referenced in function _main
aout.exe : fatal error LNK1120: 2 unresolved externals
由于xyz.cpp中没有使用ctor或dtor,因此不需要从那里进行实例化。无论好坏,这就是模板的工作方式。xyz
的实例化,在这个示例中是xyz<int>
。在粗暴的尝试中,可以通过在xyz.cpp末尾添加以下行来实现:template xyz<int>;
这个请求要求实例化所有的xyz<int>
。但是这种方法不太合适,因为每次引入一个新的xyz类型时,都需要修改实现文件xyz.cpp。一种更不具侵入性的避免此文件的方法是创建另一个文件:
// xyztir.cpp
#include "xyz.cpp" // .cpp file!!!, not .h file!!
template xyz<int>;
"xyz.cpp"
包含到xyz.h
的末尾:// xyz.h
// ... previous content of xyz.h ...
#include "xyz.cpp"
// xyz.h
export
// ... ORIGINAL contents of xyz.h ...
通过包含xyz.h文件,xyz.cpp中的构造函数和析构函数将被导出。因此,在这种情况下,您不需要xyztir.cpp,也不需要在xyz.cpp末尾进行实例化请求,也不需要手动将构造函数或析构函数带入xyz.h。使用先前显示的命令行,编译器可能会自动为您完成所有操作。
export
功能已经消失了。此外,请注意,唯一一个支持 export
的编译器实现者也推动将此功能从新标准中移除。 - David Rodríguez - dribeasexport
允许你在编写模板类时将声明(即头文件)与定义(即代码)分开。如果你的编译器不支持 export
,那么你需要把声明和定义放在同一个位置。目前(据我所知),唯一支持导出模板的编译器是Comeau、Borland C++ Builder X附带的编译器(但不包括当前版本的C++ Builder)以及英特尔(至少是非官方的,如果不是官方的话,我不确定)。
export
关键字已从标准中删除,并且可能永远不会在另一个编译器中实现。 - Felix Dombek