【问题标题】:Using export keyword with templates将 export 关键字与模板一起使用
【发布时间】:2011-03-24 09:07:26
【问题描述】:

据我了解,可以使用“export”关键字,以便可以通过头文件公开模板类或函数签名,并将实际实现抽象到库文件中。
谁能提供一个实用的示例程序来说明如何做到这一点?
使用它时是否有任何缺点或需要注意的要点?

编辑:基于答案的后续问题。正如答案中提到的那样,“导出”在 C++0x 中已被弃用,即使对于 C++03x,编译器也很少支持。鉴于这种情况,如何在 lib 文件中隐藏实际实现,只通过头文件公开声明,以便最终用户可以知道公开 API 的签名是什么,但无法访问实现相同的源代码?

【问题讨论】:

  • 我还不知道所有编译器都支持它。我认为 Comeau 是少数拥有它的人之一。
  • This C++ FAQ-Lite entry 似乎回答了你的问题。
  • C++0x 中没有弃用 export 吗?此外,它在 C++03 中不可用(Comeau 编译器除外)。
  • @Alexandre C:考虑过弃用它 (herbsutter.com/2009/10/23/…),但我没有完全遵循。
  • “正如答案中提到的'export'在 C++0x 中已弃用”,如果他们这样说,这些答案是不正确的。该关键字已从 C++0x 中完全删除。

标签: c++ templates c++11 export


【解决方案1】:

首先:大多数编译器(包括 gcc、Clang 和 Visual Studio)不支持 export 关键字。

它已在单个前端实现:EDG 前端,因此只有使用它的编译器(Comeau 和 icc)支持此功能。来自 EDG 实现者的反馈非常简单:我们花了很多时间,非常复杂,我们建议不要实现它 (1),因此它已在 C++0x 中被删除。

现在,标准允许(至少由 gcc 实现):

  • 在标头中声明模板函数的专用版本
  • 在单个源文件中定义此特化

并让它的行为与您对常规函数的期望一样。

注意:正如 Johannes 在评论中指出的那样,如果在标头中定义了函数的完全特化,则必须将其标记为内联,否则链接器会报错。

编辑:

(1) 终于找到了我的参考资料 Why can't we afford export (PDF) Tom Plum,由 Edison Design Group 的 Steve Adamczyk、John Spicer 和 Daveed Vandevoorde 审核,他们最初在 EDG 前端实现了它。

【讨论】:

  • 这实际上不是导致 C++0x 弃用的论文。 (这是 2003 年的论文)事实上,该提案以相当大的优势被否决(IIRC,大约 2/3 赞成在非正式投票中保留 export,没有进入正式投票)
  • @MSalters:我从来没有打算这么说,我会说得更清楚:)
  • “在标头中声明模板函数的专用版本,以在单个源文件中定义此专用版本”。嗯。这完全是规范所要求的。函数模板的显式特化是函数(不是模板),实际上不能可靠地在标题中定义,除非它们是内联(否则会出现多个定义错误)。我误会你了吗?
  • ...如果互相压倒,包括 C++ 的内联模板,结果...灾难。 :-(
【解决方案2】:

【讨论】:

  • The keyword is unused and reserved. 看起来更像“它还没有实现”而不是“它已经过时了”。还是谢谢
  • 实际上,在 c++ 2003 中定义了功能导出关键字。基本上没有编译器实现过该功能。在 c++ 2011 中,该功能已从 c++ 标准中删除。 export 关键字仍然保留,但没有任何功能。然而,张贴者明确询问了与已从 C++ 中删除的 export 关键字相关的 c++ 2003 功能。
  • 我明白了,这就解释了为什么它一直未被使用。
  • 模块又回来了。
【解决方案3】:

很难提供示例程序,因为几乎没有编译器支持导出。 g++ 将报告一个警告说它不受支持,并且 IIRC 它甚至不会在 Visual Studio 中编译。此外,导出在 C++0x 中已被弃用,这意味着未来的编译器根本不可能支持它。

关于如何在少数支持它的编译(即 Comeau C++)中使用 export 的讨论,check out this link 这也解释了为什么 export 难以实现。

如果这被视为主要的反出口咆哮,我们深表歉意。我保证我不讨厌出口!它只是没有得到广泛的支持,你不能真正依赖它作为程序员。

【讨论】:

    【解决方案4】:

    许多编译器供应商不支持它的原因是,即使它可以工作,也不是程序员所期望的那样。

    我在这些问题上找到的最好的文章在这里:

    http://msmvps.com/blogs/vandooren/archive/2008/09/24/c-keyword-of-the-day-export.aspx

    你最好实例化你的模板。

    【讨论】:

      【解决方案5】:

      我读到一篇文章,其标题类似于“不支持导出”,而且无论如何它都无法满足您的要求。

      如前所述,做你想做的事的唯一方法就是完全专业化。但更重要的是,如果你看不到库的源代码,那么你就无法编译它。这意味着您不能接受其中的动态内存,因为不能保证您将使用匹配的删除到他们的新内存。例如,如果我的代码是调试的并且库是发布的,那么删除器将与新的不匹配。您可以使用 shared_ptr 并提供一个删除器,但那是 TR1 并且没有导出。

      【讨论】:

        【解决方案6】:

        export 关键字在 C++20 中受支持,并与模块语言功能 (https://en.cppreference.com/w/cpp/language/modules) 一起使用。

        【讨论】:

          【解决方案7】:

          C++11 现在有“外部模板”,现代编译器已经很好地支持了。

          【讨论】:

            猜你喜欢
            • 2012-05-19
            • 1970-01-01
            • 1970-01-01
            • 2019-11-26
            • 1970-01-01
            • 1970-01-01
            • 2019-02-01
            • 2016-06-02
            • 1970-01-01
            相关资源
            最近更新 更多