【问题标题】:Undefined reference to defined function对已定义函数的未定义引用
【发布时间】:2013-07-19 20:01:16
【问题描述】:

我有一个非常奇怪的错误:我有一对 .h 和 .cpp 文件,其中包含一些函数和常量。当我尝试编译它时,g++ 对函数说“未定义的引用”。函数原型和定义似乎是一样的。除了必要的行之外,我已经将所有内容都注释掉了,而 g++ 仍然抱怨它。

我的程序目前是(在注释掉所有内容之后):

main.cpp

#include "a.h"

int main(){
    makehex(10);

    return 0;
}

啊。

#include <iostream>
#include <sstream>

#ifndef __A___

static const std::string b = "01";
static const std::string d = b + "23456789";
static const std::string h = d + "abcdef";

template <typename T> std::string makehex(T value, unsigned int size = 2 * sizeof(T));
#endif

a.cpp

#include "a.h"

template <typename T> std::string makehex(T value, unsigned int size){
    // Changes a value to its hexadecimal string
    if (!size){
        std::stringstream out;
        out << std::hex << value;
        return out.str();
    }
    std::string out(size, '0');
    while (value && size){
        out[--size] = h[value & 15];
        value >>= 4;
    }
    return out;
}

只有 1 个函数。我不明白这怎么会出错。

我用g++ -std=c++11 main.cpp a.cpp 编译并得到错误:

main.cpp:(.text+0x1a): undefined reference to `std::string makehex<int>(int, unsigned int)'
collect2: error: ld returned 1 exit status

是因为模板吗?如果是这样,我该如何解决?

【问题讨论】:

标签: c++ g++ undefined-reference


【解决方案1】:

常见的模板错误。编译器在编译时需要知道模板的定义,因此模板函数的定义必须在头文件中。

【讨论】:

  • 或者,必须在 .cpp 文件中实现模板的特化。
  • @calccrypto 你认为template &lt;typename T&gt; std::string makehex(T value, unsigned int size) 是什么?
  • @H2CO3 哈是的,没错,我第一次这样做的时候就搞砸了。
【解决方案2】:

您需要了解模板本身并不是代码,而是告诉编译器如何生成程序的其他部分可以使用的代码。为了让编译器能够自动执行此操作,它必须在实例化时看到该模板的定义

但在您现有的设置中,只有makehex&lt;T&gt;()声明main.cpp 中可见。 makehex&lt;T&gt;() 的实际定义被隐藏在 a.cpp 中,main 在编译期间并不知道(它在不同的翻译单元中)。解决此问题的简单方法是将 makehex&lt;T&gt;() 的实现从 a.cpp 移动到啊

【讨论】:

    【解决方案3】:

    仅当您实际实例化模板时才会发出模板函数。您正尝试在主函数中执行此操作,使用调用 makehex(10)

    您已在 main.cpp 文件中包含“a.h”,因此在编译 main.cpp 时,您可以访问函数的声明。但是,编译器无法访问 定义,因为它位于另一个未包含的文件 (a.cpp) 中。

    短期修复是在 main.cpp 中的 #include "a.cpp"。但是,长期的解决方法是不要为模板函数定义提供 .cpp 文件 - 将其全部放在头文件 (.h) 中。 (这不适用于普通函数/类等)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 2020-02-10
      • 2021-06-08
      • 2022-05-03
      相关资源
      最近更新 更多