实现类模板的成员函数 [duplicate]

Implementing member functions of a class template [duplicate]

提问人:CoAstroGeek 提问时间:11/2/2023 最后编辑:Ted LyngmoCoAstroGeek 更新时间:11/2/2023 访问量:54

问:

好的,我想我错过了一些关于模板的基本知识。

我有一类星历数据,最初定义为:

class EphemerisPoint;
class Ephemeris
{
 private:
    vector<EphemerisPoint> data;

 public:
    StateVector interpolate(double time);
};

其中插值在 CC 文件中定义:

StateVector Ephemeris::interpolate(double time)
{
...
}

我有一个用例,我想用 boost::circular_buffer<> 替换 vector<>

所以我把它做成一个类模板:

class EphemerisPoint;
template <class T> class Ephemeris
{
 private:
    T data;

 public:
    StateVector interpolate(double time);
};

以及 interpolate() 的实现:

template<class T> StateVector Ephemeris<T>::interpolate(double time)
{
...
}

这些都编译到一个库中。

但是当我使用它时:

Ephemeris<boost::circular_buffer<EphemerisPoint> > ephem;

ephem.interpolate(10.0);

它编译良好 - 但是当链接到库时,我收到如下消息:

undefined reference to `Ephemeris<boost::circular_buffer<EphemerisPoint, std::allocator<EphemerisPoint> > >::propagate(double)'

如果我通过 nm 运行库,我会看到库中没有 Ephemeris::interpolate??

但是,如果在这个大型库的其他地方,我实例化并使用 Ephemerisboost::circular_buffer<EphemerisPoint >对象,那么 boost::circular_buffer 的相应 Ephemeris::interpolate() 函数将存在于库中,我可以在链接到它的程序中使用它。

但是,如果我尝试实例化旧的基于向量的向量,则不会再次链接。

我是否必须使用我打算使用的每种模板类型在库中实例化 Ephemeris 版本?这似乎与我认为模板的工作方式不一致。

gcc 4.8.5,在 CentOS 7 FWIW 上使用 -std=gnu++11

C++ 模板

评论

1赞 Pepijn Kramer 11/2/2023
模板(成员)函数的实现应在头文件中的类内。而且,您不能同时拥有具有相同名称的非模板化类和模板化类
0赞 CoAstroGeek 11/2/2023
哇 - 好吧,我的意思是我想我可以。但这是一个具有许多大型方法(各种文件格式的解析器等)的类 - 源文件几乎 10K 行。
0赞 Ben Voigt 11/2/2023
@PepijnKramer:在头文件中是。在班级内,请不要。保持井井有条。通过 #include 帮助程序头文件,如果这有助于组织。
0赞 PaulMcKenzie 11/2/2023
@CoAstroGeek -- Visual C++ 中的标题几乎是 10K 行,所以这并不奇怪。<algorithm>
0赞 Igor Tandetnik 11/2/2023
他们是休息时间。编译器需要在使用模板时查看实际实现,并且其参数已知。

答:

-1赞 CoAstroGeek 11/2/2023 #1

好的,上面的评论让我找到了一个答案,该答案不涉及将 10K 行代码移动到我的头文件中。

如何避免模板函数出现链接器错误?

我认为这也可以让我将允许的模板类限制为 vector 和 boost::circular_buffer

去尝试一下 - 这可能是许多其他问题的重复,例如:将 C++ 模板函数定义存储在 .CPP 文件,所以如果你愿意,请随时关闭它。

评论

2赞 user4581301 11/2/2023
一些使用说明:避免写本质上是“这样做:<链接到现有答案>”的答案。相反,将现有答案作为副本提出。在测试解决方案有效之前,不要做出答案。如果没有,当你发现并回来修复它时,你可能会发现它已经被否决到海底(如果答案太糟糕以至于很危险,甚至可能被删除)。与问题不同,人们有一种内在的激励机制,让他们返回并重新评估改进的答案,但如果反对者不知道答案已经更新......