如何实现导出模板? 导出模板是2011年前C++中的一个特性,其中模板的实现将被推迟到单独的源文件。
,可以通过手动指定实现文件中使用的每种类型来编写“手动”导出模板。由于这将简单地创建特定的符号——我相信这与重载函数的方式类似——因此如何实现这一点是有意义的 但据我所知,导出的模板(通过如何实现导出模板? 导出模板是2011年前C++中的一个特性,其中模板的实现将被推迟到单独的源文件。,c++,templates,compiler-construction,c++98,C++,Templates,Compiler Construction,C++98,,可以通过手动指定实现文件中使用的每种类型来编写“手动”导出模板。由于这将简单地创建特定的符号——我相信这与重载函数的方式类似——因此如何实现这一点是有意义的 但据我所知,导出的模板(通过export关键字)是任意的。它可以允许传递任何类型的数据 举个简单的例子: template<typename T> T add(T value1, T value2) { return value1 + value2; } 模板 T添加(T值1,T值2){ 返回值1+2; } 如果T
export
关键字)是任意的。它可以允许传递任何类型的数据
举个简单的例子:
template<typename T>
T add(T value1, T value2) {
return value1 + value2;
}
模板
T添加(T值1,T值2){
返回值1+2;
}
如果T是int
,float
,或者特别是std::string
(以及任何其他重载+
运算符的类型),则此示例的程序集输出将大不相同
由于它是完全任意的,编译器如何实现这个关键字
我的猜测是在链接时生成代码,这很可能需要自定义对象文件格式,其中包含一些代码表示。但这也使得链接器成为一个编译器,这打破了预处理器-编译器-链接器的分离。模板化的东西只有在被编译的代码引用时才被实例化为具体类型 此时,编译器需要所有信息(结构定义、函数定义)才能生成代码 如果编译器在导入结构时看到的唯一定义是
export templat< ... > class foo;
导出模板<…>foo类;
它没有生成代码的机制,并且在请求类foo的特性时失败
相反,在构建库时,编译器可以使用定义和实现,但它看不到库可能使用哪些类型
唯一可用的(需要的?)机制是头文件。这具有定义和实现,并且避免了对特殊对象格式的需要
如果您显式地实例化了模板的具体示例,则可以从库中导出这些示例,但只能导出已知类型。大约在2001年,EDG实现了导出,Comeau为我提供了早期构建。我确实能够实例化
A
,其中A
在A.cpp中定义,而B
在B.cpp中定义。显然,这需要某种形式的链路时间代码生成
这更令人惊讶,因为Comeau实际上使用MSVC作为后端,而微软同时认为这是不可能的!(这就是我首先评估导出的原因,WG21文件N1426)有一个神话,一些人希望导出的模板严格独立于编译器,但没有证据表明这些人(如果他们存在的话)是委员会成员 导出的模板实际上是具有普通模板语义的普通模板。(它们与O'Caml或Haskell模块不同。) 产生二进制代码的单独编译是基于ABI的。为函数模板(与其实例化相反)创建ABI是没有意义的 <>强> C++中的模板基本上是类似于< /强>的宏。不是蹩脚的C/C++预处理器宏,它是基于令牌的,因此忽略C或C++语法结构,但是它们非常接近于替换(在语法实体而不是词素杠杆)。 他们倾向于从实例化上下文中提取大量的名称,比我们想要的更多。这是因为C++中没有“概念”元类型系统。(C++过于复杂,太不规则,无法修改这样的东西。) 没有C++模板的“概念”契约,C++语言定义不能严格限制在实例化上下文中查找的名称:甚至是明显的,如<代码>