3

我想创建一个模板类(我们称之为Foo),它只接受一些特定的类型参数(我们只说doubleand float)。通常模板在头文件 ( .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_dand编写单独的声明Foo_f

4

2 回答 2

6

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

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_f来自模板的实例化。用于模板的任何其他类型都将导致链接错误,因为它们的实例化将不存在。或者,更迂腐的是,编译器像往常一样按需创建实例化,但它无法解析对应于类方法的符号,因为这些符号的显式实例化不存在。FooFoo

于 2012-06-12T01:07:42.460 回答
5

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

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

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

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

最后两行强制编译器在这个翻译单元中实例化模板,所以你不会得到任何链接器错误。

希望这可以帮助!

于 2012-06-12T00:45:24.963 回答