导出MSVC模板是否真的有用?

4
当你在MSVC的公共接口中创建一个包含模板数据成员的结构体时,编译时会出现警告。
其中一种解决方案是在DLL中导出模板类型(请参见this KB文章)。
我提出这个问题是因为我不知道为什么要导出该类型?
  1. 如果不导出它,则.hpp文件具有足够的信息来自动生成该类型。

  2. 如果它是标准库类型,并且您有两个或更多dll,每个dll可能链接到不同版本的标准库,则现在在代码中有多个相同类型的二进制版本。

这有什么意义?情况#1可能会导致运行时崩溃,如果编译器认为它们实际上是不同的两个版本,但#2可能只是由于缺少符号而无法加载?
我完全误解了吗?在我看来,最好的选择是忽略MSVC的警告。

编辑:目前还没有人指出这一点,但我知道并理解如果您的模板中有静态内容,并且希望这些静态内容在单个应用程序中的DLL的所有使用中共享:在这种情况下,您必须导出模板实例化。对于单例对象、日志记录器等情况,这是至关重要的。


1
我们在这里禁用了那个警告,从未出现过问题。可能只是运气好而已。 - stijn
最终,我们也选择了禁用警告的路线。 - lefticus
1个回答

1

#2 是即时死亡。如果您想在 DLL 接口中使用标准类型,您必须确保使用代码 a) 动态链接到相同的 CRT DLL,并且 b) 使用相同的头文件进行编译。

#1 的存在是因为您无法保证被调用的代码与您的代码相同-例如,特殊化等。如果您自己编写了该类并保证客户端和 DLL 看到完全相同的类,则没有任何问题。


那么这是否意味着您同意我的评估,即禁用警告是唯一真正的答案?要么您拥有相同的版本并且一切正常,要么您没有相同的版本,然后您要么1)崩溃,要么2)无法互操作? - lefticus
@lefticus:警告通常不应该被禁用-它们很重要。您应该按类型禁用它们,也就是说,仅针对您知道在共享头文件中完全定义的类型禁用它们。 - Puppy
我想我应该澄清一下,我特指标准库类型。那些在头文件中没有完全实现且您无法真正控制的类型。然而,这个问题几乎是无意义的,因为我链接的 KB 文章明确表示,唯一可能导出的类型是 std::vector。 - lefticus
@lefticus:在这种情况下,你应该保留警告,因为它们准确地警告你正在做一些非常错误的事情——除非你规定了我在#2中提到的条件。 - Puppy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接