在.cpp中定义模板并保留"genericness"

Define template in .cpp and retain "genericness"

本文关键字:保留 genericness cpp 定义      更新时间:2023-10-16

免责声明:在开始将其标记为重复问题之前,请全面阅读。谢谢。

我真的不喜欢标题中定义模板函数/类。我想知道是否有更优雅的解决方案。

说我有一堂课,喜欢:

// A.h
template<typename T>
class A
{
    ...
};

我偶然发现了多个半分解:

  • 还将定义源文件包含在客户端源文件中:
    #include "A.h"
    #include "A.cpp"
  • 在类模板标题中包含定义源,但请从编译中删除CPP文件
  • 显式模板实例化template class A<int>;

前两个解决方案有效,但它们看起来……好,丑陋。

在所有这些解决方案中,最后一个似乎是最优雅的(至少对我来说),但是这样我就会失去模板的"通用",因为我必须针对每种类型实例化。

任何人都可以告诉我(如果可能的话)将定义与声明分开,同时仍保留模板类的通用性?

喜欢第一个或第二个,我建议这样做:

// C.h
template <typename T> class C
{
    C();
}
#include "C_impl.h"
//C_impl.h
template <typename T> C<T>::C() { }

不幸的是,由于编译器需要即时模板

,因此无法完美分开定义和声明。

定义.h文件中的方法没有错,但是我更喜欢使用扩展名.hpp

您可能会考虑的其他选项是:

在文件顶部声明类,并在底部定义方法。

// A.hpp
template<typename T>
class A {
    void someMethod();
    ...
};
template <class T> A<T>::someMethod() {
    // code
}

将实现放入.ipp文件中,并将其包含在.hpp文件的末尾:

// A.hpp
template<typename T>
class A {
    void someMethod();
    ...
};
#include "detail/A.ipp"

// detail/A.ipp   
template <class T> A<T>::someMethod() {
    // code
}

.ipp文件上的说明:http://lists.boost.org/archives/boost/2003/08/51197.php:

如果要将模板源拆分为界面,并且 实施(有很多充分的理由这样做,包括 控制实例),您不能很好地使用相同的名称 (foo.hpp)两次,而foo.cpp都不适合任何一个。 foo.ipp清楚地将文件描述为预期的实现文件 在foo.hpp。

我在某些标题中看到的模板类定义将在标题中,并且实现将包含在带有扩展名的文件名中。包含在标题文件的末尾。

这样,您的标题将是干净的,并且包括此标头文件的人将自动通过" INL"文件,提供的" INL"文件也与标头文件一起分发。