“未定义的符号” 简单模板类的链接器错误

发布于 2024-07-24 08:14:48 字数 896 浏览 13 评论 0原文

远离 C++ 几年了,我从以下代码中收到链接器错误:

Gene.h

#ifndef GENE_H_INCLUDED
#define GENE_H_INCLUDED

template <typename T>
class Gene {
    public:
    T getValue();
    void setValue(T value);
    void setRange(T min, T max);

    private:
    T value;
    T minValue;
    T maxValue;
};

#endif // GENE_H_INCLUDED

Gene.cpp

#include "Gene.h"

template <typename T>
T Gene<T>::getValue() {
    return this->value;
}

template <typename T>
void Gene<T>::setValue(T value) {
    if(value >= this->minValue && value <= this->minValue) {
        this->value = value;
    }
}

template <typename T>
void Gene<T>::setRange(T min, T max) {
    this->minValue = min;
    this->maxValue = max;
}

使用 Code::Blocks 和 GCC(如果这对任何人都很重要)。 另外,为了乐趣和练习,明确将一些 GA 内容移植到 C++。

Been away from C++ for a few years and am getting a linker error from the following code:

Gene.h

#ifndef GENE_H_INCLUDED
#define GENE_H_INCLUDED

template <typename T>
class Gene {
    public:
    T getValue();
    void setValue(T value);
    void setRange(T min, T max);

    private:
    T value;
    T minValue;
    T maxValue;
};

#endif // GENE_H_INCLUDED

Gene.cpp

#include "Gene.h"

template <typename T>
T Gene<T>::getValue() {
    return this->value;
}

template <typename T>
void Gene<T>::setValue(T value) {
    if(value >= this->minValue && value <= this->minValue) {
        this->value = value;
    }
}

template <typename T>
void Gene<T>::setRange(T min, T max) {
    this->minValue = min;
    this->maxValue = max;
}

Using Code::Blocks and GCC if it matters to anyone. Also, clearly porting some GA stuff to C++ for fun and practice.

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

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

发布评论

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

评论(4

一个人的旅程 2024-07-31 08:14:48

必须在实例化给定模板类之前包含模板定义(代码中的 cpp 文件),因此您要么必须在标头中包含函数定义,要么在使用该类之前 #include cpp 文件(或者显式执行实例化(如果数量有限)。

The template definition (the cpp file in your code) has to be included prior to instantiating a given template class, so you either have to include function definitions in the header, or #include the cpp file prior to using the class (or do explicit instantiations if you have a limited number of them).

另类 2024-07-31 08:14:48

包含包含模板类函数实现的 cpp 文件是有效的。 然而,恕我直言,这很奇怪而且尴尬。 一定有更巧妙的方法来做到这一点吗?

如果您只有几个不同的实例需要创建,并且事先知道它们,那么您可以使用“显式实例化”,

其工作原理如下:

在gene.cpp的顶部添加以下行

template class Gene<int>;
template class Gene<float>;

Including the cpp file containing the implementations of the template class functions works. However, IMHO, this is weird and awkward. There must surely be a slicker way of doing this?

If you have only a few different instances to create, and know them beforehand, then you can use "explicit instantiation"

This works something like this:

At the top of gene.cpp add the following lines

template class Gene<int>;
template class Gene<float>;
无妨# 2024-07-31 08:14:48

if(value >= this->minValue && value <= this->minValue) 中,第二个 minValue 应为 maxValue< /代码>,不是吗?

回应 Sean 所说的:错误消息是什么? 您已经定义并声明了这些函数,但是您没有在任何地方使用它们,我也没有看到错误(除了拼写错误之外)。

In if(value >= this->minValue && value <= this->minValue) the second minValue should be maxValue, no?

Echo what Sean said: What's the error message? You've defined and declared the functions, but you've not used them in anything anywhere, nor do I see an error (besides the typo).

恋竹姑娘 2024-07-31 08:14:48

TLDR

似乎您需要一个显式实例化实际创建该类。 由于模板类只是关于如何创建类的“指令”,因此您实际上需要告诉编译器创建该类。 否则链接器在查找时将找不到任何内容。

彻底的解释

当编译代码时,g++ 会经历许多步骤,您所看到的问题发生在链接步骤中。 模板类定义了“应该如何”创建类,它们实际上是模板。 在编译时,g++ 单独编译每个 cpp 文件,因此编译器会看到有关如何创建类的模板,但不会看到要创建哪些“类”的说明。 因此忽略它。 稍后在链接步骤中,g++ 尝试链接包含该类的文件(不存在的文件),但未能找到它,最终返回错误。

为了解决这个问题,您实际上需要“显式实例化”该类,方法是将以下几行添加到 Gene.cpp 类定义之后

template class Gene<whatever_type_u_wanna_use_t>;int

查看这些 docs 我发现它们非常有帮助。

TLDR

It seems that you need an Explicit Instantiation i.e. to actually create the class. Since template classes are just "instructions" on how to create a class you actually need to tell the compiler to create the class. Otherwise the linker won't find anything when it goes looking.

The thorough explanation

When compiling your code g++ goes through a number of steps the problem you're seeing occurs in the Linking step. Template classes define how classes "should" be created, they're literally templates. During compile time g++ compiles each cpp file individually so the compiler sees your template on how to create a class but no instructions on what "classes" to create. Therefore ignores it. Later during the linking step the g++ attempts to link the file containing the class (the one that doesn't exist) and fails to find it ultimately returning an error.

To remedy this you actually need to "explicitly instantiate" the class by adding the following lines to Gene.cpp after the definition of the class

template class Gene<whatever_type_u_wanna_use_t>;int

Check out these docs I found them to be super helpful.

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