为什么模板类的实现和声明应该在同一个头文件中?

为什么模板类的实现和声明应该在同一个头文件中? 你们中的任何一个人都可以用例子来解释吗

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

有关详细信息,请阅读“包含模型” 。

每个使用不同types实例化的地方都必须能够看到类模板的定义和其成员函数的实现。 即为了实例化myTemplate<int>您需要查看myTemplate的完整定义和实现。

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

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

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

他们不需要。

模板定义在实例化的地方(使用它的地方)是可见的,这样编译器可以在这个时候从模板中派生类/函数。

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

 // 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_ {}; 

这可以加快编译时间。

在正常类的情况下,声明就足够编译,相应的定义将被链接

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

这个区别在C ++ FAQ中有更好的解释。