如何在C ++中为实例化的模板类编写头文件?

时间:2012-06-12 00:27:22

标签: c++ templates header-files instantiation

我想创建一个只接受一些特定类型参数的模板类(我们称之为Foo)(仅假设doublefloat)。通常模板在头文件(.h)中实现,因为它不知道如何在用户代码中实例化。在这种情况下,在实现文件(.cpp)中实现类更有意义,如下所示:

// Foo.cpp:

template <class T>
class Foo
{
    // Insert members here
};

typedef Foo<double> Foo_d;
typedef Foo<float> Foo_f;

这将在编译Foo.cpp时实例化并编译该类。但是,如何在头文件中声明这一点而不为Foo_dFoo_f编写单独的声明?

2 个答案:

答案 0 :(得分:5)

除非我弄错了,否则您所描述的内容正是新C ++ 11 extern template功能的用例。要使用此功能,您可以将模板类的接口放在头文件中。然后,您将使用以下行结束头文件:

extern template class Foo<float>;
extern template class Foo<double>;

这告诉任何包含头文件的文件在使用时不要尝试实例化模板。然后,在您的C ++文件中,您将实现模板类,然后以行

结束
template class Foo<float>;
template class Foo<double>;

最后两行强制编译器在此转换单元中实例化模板,因此不会出现任何链接器错误。

希望这有帮助!

答案 1 :(得分:5)

您可以在头文件中定义模板,声明方法,但不定义它们。例如:

template <typename T>
class Foo {
    T val;
public:
    Foo (T t);
    T value ();
};

typedef Foo<double> Foo_d;
typedef Foo<float> Foo_f;

.cpp文件中,您完成方法的实现,然后实例化您想要的模板。

#include "foo_template.hpp"

template <typename T>
Foo<T>::Foo (T t) : val(t) {}

template <typename T>
T Foo<T>::value () { return val; }

template class Foo<double>;
template class Foo<float>;

目标文件应具有来自模板Foo_d显式实例化Foo_fFoo的实例化。用于模板Foo的任何其他类型都将导致链接错误,因为它们的实例化将不存在。或者,更迂腐地,编译器像往常一样按需创建实例化,但是它将无法解析与类的方法相对应的符号,因为这些符号的显式实例化将不存在。