对 ClassName::ClassName 的未定义引用

发布于 2024-09-19 16:03:21 字数 992 浏览 8 评论 0原文

我正在使用 Code::Blocks 构建我的项目,其中包含三个文件: main.cppTimeSeries.cppTimeSeries.hTimeSeries.h 提供 TimeSeries 类的声明,如下所示:

template<class XType, class YType> class TimeSeries {
public:
    TimeSeries(void);
    ~TimeSeries(void);
};

然后 TimeSeries.cpp 包含: #include "TimeSeries.h"

template<class XType, class YType>
TimeSeries<XType, YType>::TimeSeries(void) {
}

template<class XType, class YType>
TimeSeries<XType, YType>::~TimeSeries(void) {
}

最后,main.cpp 包含

#include "TimeSeries.h"
typedef TimeSeries<float, float> FTimeSeries;

int main(int argc, char** argv) {
    FTimeSeries input_data;
    return 0;
}

使用 C::B 构建时,出现以下错误:

undefined reference to `TimeSeries<float, float>::TimeSeries()'

我该怎么办?

谢谢,
金融理财师。

I'm using Code::Blocks to build my project, which contains three files: main.cpp, TimeSeries.cpp, TimeSeries.h. TimeSeries.h provides declarations for the TimeSeries class as follows:

template<class XType, class YType> class TimeSeries {
public:
    TimeSeries(void);
    ~TimeSeries(void);
};

Then TimeSeries.cpp contains:
#include "TimeSeries.h"

template<class XType, class YType>
TimeSeries<XType, YType>::TimeSeries(void) {
}

template<class XType, class YType>
TimeSeries<XType, YType>::~TimeSeries(void) {
}

And finally, main.cpp contains

#include "TimeSeries.h"
typedef TimeSeries<float, float> FTimeSeries;

int main(int argc, char** argv) {
    FTimeSeries input_data;
    return 0;
}

When building with C::B, I get the following error:

undefined reference to `TimeSeries<float, float>::TimeSeries()'

What can I do?

Thanks,
CFP.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

远山浅 2024-09-26 16:03:22

基本上所有模板化代码都应该在标头中定义,否则将不会构建它,因为编译单元中没有任何内容使用它。

每个 cpp 文件都被编译为一个单独的单元,因此构造函数和析构函数不会被编译。编译器在编译 TimeSeries.cpp 时无法知道您将在 main.cpp 中使用什么类型的模板参数。

Basically all templated code should be defined in a header, otherwise it will not be built since nothing uses it in the compiled unit.

Each cpp file is compiled as a separate unit, and thus constructor and destructor are not compiled. The compiler has no way of knowing what type of template argument you will use in main.cpp when it compiles TimeSeries.cpp.

℉服软 2024-09-26 16:03:22

将代码拆分为头文件和源文件的原因是为了将声明和实现分开。编译器可以将源文件(编译单元)翻译成目标文件,而其他想要使用类和函数的编译单元只需包含头文件,并链接目标文件即可。这样,代码只需编译一次,并且可以通过链接来重用。

模板的问题在于,只要没有为它们提供参数,编译器就无法编译它们。使用不同参数实例化的同一模板会产生不同的类型。从编译器的角度来看,std::vectorstd::vector 没有任何关系。因此,模板类通常必须完全驻留在头文件中,因为当使用模板时,编译器需要完整的定义才能根据参数生成类。

正如 @Gabriel Schreiber 在他的答案中指出的那样,您可以告诉编译器他应该使用一组特定的参数来编译模板,只需通过链接即可将其提供给其他编译单元。但是,这并不使该模板可用于其他参数集。

The reason for splitting code into header- and source-files is so that the declaration and the implementation are separated. The compiler can translate the source-file (compilation unit) into an object file, and other compilation-units that want to use the classes and functions just include the header-file, and link the object file. This way, the code has to be compiled only once, and can be reused by linking it.

The problem with templates is that, as long as there are no parameters provided for them, the compiler cannot compile them. The same template instantiated with different parameters results in different types. std::vector<int> and std::vector<float> are, from the compilers perspective, not related in any way. Because of this, template-classes usually have to reside completely in a header-file, because, when the template is used, the compiler needs the complete definition in order to generate the class depending on the parameters.

As @Gabriel Schreiber pointed out in his answer, you can tell the compiler that he should compile the template with a specific set of parameters, making that available to other compilation units just by linking. However, this does not make the template available for other parameter sets.

伏妖词 2024-09-26 16:03:22

您需要将其添加到您的 .cpp 文件中(定义下方):

template class TimeSeries<float, float>;

当编译器编译 TimeSeries.cpp 时,它不知道模板需要哪种类型,因为它在另一个源文件中使用。您需要明确地告诉编译器。

在 Stroustrup 副本或互联网上阅读有关显式模板实例化的信息。

You need to add this in your .cpp-file (below the definitions):

template class TimeSeries<float, float>;

When the compiler compiles TimeSeries.cpp it doesn't know which for which types the template is need because it is used in another source file. You need to tell the compiler explicitly.

Read about Explicit Template Instantiation in your copy of the Stroustrup or on the internet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文