链接器错误:使用外部变量的函数模板中未定义的引用

Linker error: undefined reference in a function template that uses external variables

提问人:Fan Zheng 提问时间:5/25/2020 最后编辑:Fan Zheng 更新时间:5/25/2020 访问量:310

问:

我有一个包含两个文件的迷你项目:

main.cpp

#include <string>
template<int I>
int getint(int i)
{
    extern std::string var;
    return var.size() * i;
}

int main()
{
    return getint<2>(2);
}

和子.cpp

#include <string>
extern std::string var;
std::string var = "Hello";

但是当我编译项目时,链接器给出错误:

-------------- Clean: Debug in test (compiler: GNU GCC Compiler)---------------

Cleaned "test - Debug"

-------------- Build: Debug in test (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall -fexceptions -g  -c C:\Users\Fan\Downloads\test\test\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -Wall -fexceptions -g  -c C:\Users\Fan\Downloads\test\test\sub.cpp -o obj\Debug\sub.o
mingw32-g++.exe  -o bin\Debug\test.exe obj\Debug\main.o obj\Debug\sub.o   
obj\Debug\main.o: In function `Z6getintILi2EEii':
C:/Users/Fan/Downloads/test/test/main.cpp:6: undefined reference to `var'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
2 error(s), 0 warning(s) (0 minute(s), 0 second(s))

我不知道这是怎么发生的,因为只要我稍微简化程序,问题就会消失。

  1. 如果我将 getint() 设置为普通的旧函数而不是函数模板,则编译成功。

  2. 如果我将行“extern std::string var;”移到函数之外(比如说到它上面的一行),那么编译就成功了。

  3. 如果我将 var 的类型更改为 int(并在 main.cpp 中省略“.size()”,并在 sub.cpp 中为其赋值 1),则编译成功。

这似乎是阻止我原始项目编译的奇怪因素组合。我不知道他们在:(

编辑:为了响应“无法重现”的备注,我正在尝试使用 Code::Blocks 17.12 在本地 Windows 7 机器上进行编译。编译器和链接器的输出已更新为包含编译器标志。

C++ 链接器错误 未解决的外部 函数模板

评论

0赞 user1810087 5/25/2020
无法重现:coliru.stacked-crooked.com/a/aebbaf78ae41fc64 ...您使用什么编译器版本和标志?
0赞 HolyBlackCat 5/25/2020
也无法在这里重现,也不能在我的本地机器上重现(使用 MSYS2 GCC,也不使用 Clang)。您使用什么编译器(包括版本)?
0赞 yaodav 5/25/2020
#ifdef MAIN :)的好把戏
2赞 HolyBlackCat 5/25/2020
“使用 Code::Blocks 17.12”众所周知,CB 附带了一个古老的编译器。这可能是也可能不是编译器错误,但无论如何,您都应该更新编译器。
1赞 user1810087 5/25/2020
快速确认:Code::Blocks 17.12 使用 GCC 5.1.0,GCC 5(在此测试用例中20171010 gcc 版本 5.5.0)不编译此版本。

答: 暂无答案