【问题标题】:Why should the implementation and the declaration of a template class be in the same header file? [duplicate]为什么模板类的实现和声明应该在同一个头文件中? [复制]
【发布时间】:2011-04-14 12:40:13
【问题描述】:

为什么模板类的实现和声明应该在同一个头文件中?谁能举例说明一下?

【问题讨论】:

  • 它们必须在同一个编译单元中可见。如果两者都包含,它们可以在不同的文件中
  • 实际上在两个文件中拆分声明和实现并不少见。标头通常包含实现文件。
  • @MSalters:模板类有问题,这就是这个问题的意义所在。我希望我能对 cme​​ts 投反对票。
  • @Tomalak Geret'kal:一点也不。您在“Foo.h”中有一个声明,在“Foo.impl”中有定义。标头保护之前的“foo.h”的最后一行是“#include”Foo.impl。预处理器运行后,就没有区别了。它们可能在不同的文件中,但它们在同一个翻译单元中结束(s) - 这对编译器很重要。
  • @MSalters:好的,好的。实际上,我设法完全倒着读了你的最后一句话。 :)

标签: c++ templates


【解决方案1】:

编译器需要访问整个模板定义(不仅仅是签名),以便为模板的每个实例化生成代码,因此您需要将函数的定义移动到您的头文件中。

更多详情请阅读The Inclusion Model

【讨论】:

【解决方案2】:

类模板的定义及其成员函数的实现必须对使用不同类型实例化它的每个地方都是可见的。即,为了实例化myTemplate<int>,您需要查看myTemplate 的完整定义和实现。

最简单的方法是将模板的定义及其成员函数放在同一个头文件中,但还有其他方法。例如,您可以将成员函数实现放在单独包含的单独文件中。然后你可以从第一个头文件中包含它,或者只在你需要的地方包含实现文件。

例如,一种做法是在一个 .cpp 文件中为不同的参数集显式实例化模板,并在标题中声明这些实例化 extern。这样,这些实例可以在其他源文件中使用,而不需要模板成员函数的实现可见。但是,除非您包含实现文件,否则您将无法使用其他模板参数集。

即如果您将myTemplate<int>myTemplate<std::string> 定义为extern,那么您可以正常使用它们,但如果myTemplate<double> 未定义extern,那么您不能在没有实现的情况下使用它。

【讨论】:

    【解决方案3】:

    他们不必这样做。

    模板定义必须在实例化点(使用它的地方)可见,以便编译器此时可以从模板派生类/函数。

    然而,模板类使用两个头文件是极其常见的:

    // foo_fwd.hpp
    template <typename T, typename U> struct Foo;
    
    // foo.hpp
    #include "foo_fwd.hpp"
    
    template <typename T, typename U> struct Foo { typedef std::pair<T,U> type; };
    

    这允许那些不需要完整模板定义的人包含一个更轻的标题,例如:

    //is_foo.hpp
    #include <boost/mpl/bool.hpp>
    #include "foo_fwd.hpp"
    
    template <typename Z>
    struct is_foo: boost::mpl::false_ {};
    
    template <typename T, typename U>
    struct is_foo< Foo<T,U> >: boost::mpl::true_ {};
    

    这可以加快编译时间。

    【讨论】:

      【解决方案4】:

      在普通类的情况下,声明就够编译了,对应的定义会链接

      在模板的情况下,编译器还需要定义来生成代码。

      C++ FAQ 更好地解释了差异。

      【讨论】:

        猜你喜欢
        • 2013-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-09
        相关资源
        最近更新 更多