在.cpp中定义模板并保留“泛型”

时间:2014-01-24 14:48:25

标签: c++ templates

免责声明:在您开始将此标记为重复问题之前,请完整阅读。谢谢。

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

说我有一个班级,如此:

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

我偶然发现了多个半解决方案:

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

前两个解决方案有效,但看起来......好吧,丑陋。

在所有这些解决方案中,最后一个似乎是最优雅的(至少对我而言)但这种方式我失去了&#34;通用性&#34;模板,因为我必须为每种类型实例化它。

有人可以告诉我一种方法(如果可能的话)将定义与声明分开,同时仍然保留模板类的通用性吗?

3 个答案:

答案 0 :(得分:1)

像第一或第二,我建议这样:

// C.h
template <typename T> class C
{
    C();
}

#include "C_impl.h"

//C_impl.h
template <typename T> C<T>::C() { }

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

,因此无法完美地分离定义和声明

答案 1 :(得分:1)

.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中#included。

答案 2 :(得分:1)

我在一些标题中看到模板类定义将在标题中,实现将包含在扩展名为“.inl”的文件名中,并且此“inl”文件将包含在头文件的末尾。

这样你的标题将是干净的,任何包含此头文件的人都将自动包含通过“inl”文件的实现,前提是“inl”文件也随头文件一起分发。