【问题标题】:Elegant solution to implementing c++ templates实现 C++ 模板的优雅解决方案
【发布时间】:2021-12-31 05:58:11
【问题描述】:

灵感来自2009 question

背景:我目前正在从事一个小型 c++ 项目,并决定尝试创建自己的模板类。我立即遇到了十几个链接器错误。

就目前而言,我的理解是模板特化只有在绝对需要时才会生成,这意味着模板类的实现必须内联,或者在底部伴随着显式实例化。 (为什么一个暗示另一个我不太确定)

问题:为什么会这样?如果模板在单独的.cpp 文件中实现,编译顺序是否有什么特别之处使得编译器无法按需实例化模板?在我看来,标题和实现只是简单地附加在一起。

另外,我上面链接的问题最初是在十多年前发布的,一些 cmets 注意到提到的 c++-faq 引用已经过时,所以我想知道是否有新的标准支持同时启用单独的 header/实现文件隐式实例化。

【问题讨论】:

  • Is there something special about the order of compilation that makes it impossible for a compiler to instantiate the template on-demand if it is implemented in a separate .cpp file? 一个编译单元只能看到它包含的内容。 Cpp 文件通常不包括在内,因此看不到。
  • 在这方面没有任何改变,模板仍然只是头文件。 (不过,您可以使用模板做什么以及对元模板编程的支持已得到显着改进)

标签: c++ templates


【解决方案1】:

为什么会这样? 由于模板在第一阶段编译器通过两个阶段进行编译,因此主要检查语法错误。如果在你的模板中没有发现错误是合法使用的,但是在这个阶段编译器不会为它生成任何代码。在第二阶段,编译器将为您使用的模板函数的所有类成员函数生成代码。

因为模板是在编译时评估的。那么当编译器编译它时会发生什么?例如,如果您在 templated.hpp 文件中定义了一个模板,并在 implementation.cpp 文件中实现了它。编译器将每个文件分别编译成一个对象,然后链接器将它们链接在一起。由于模板是在编译时评估的,因此编译器需要在编译时实现它,如果您将它放在不同的实现文件中,这是不可用的。所以链接器向您抱怨我无法为您的此模板找到类型 T 的实现。这一切都发生在编译时。

到目前为止,直到 C++20 甚至 C++23 模板仍然需要在编译时进行评估,尽管 C++ 添加了新概念 modules,我不确定它是否可以这样使用,但你可以阅读它here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-25
    • 2018-04-28
    • 1970-01-01
    • 2011-03-31
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多