编译 C++ 代码时出现“未定义的引用”错误,但原始 makefile 代码可以编译

问题描述 投票:0回答:1

我从以下位置下载了通用 AVL 实现: http://sourceforge.net/projects/standardavl/files/standardavl/0.1/

该项目中的 makefile 正确编译了代码。编译器产生以下输出:

g++ -pedantic -Wall -O3 -c standardavl.cpp -o standardavl.o
g++ -pedantic -Wall -O3 -c Point.cpp -o Point.o
g++ -o standardavl  standardavl.o Point.o
g++ -o genpoints genpoints.o Point.o

makefile仅编译“standardavl.cpp”,因为standartavl包含“AvlTree.h”,而该文件包含“AvlTree.cpp”:

标准avl.cpp

#include "AvlTree.h"
#include "Point.h"
(...)

AvlTree.h

(...)
#include "AvlTree.cpp"

在我的项目中,我从文件 AvlTree.h 中删除了最后一行(#include“AvlTree.cpp”)并单独编译了该文件。我也不使用文件“standardavl.cpp”。我将文件 Point.h 更改为 KeyPair.h 并在那里实现了所有运算符。

我的编译器产生以下输出:

g++ -pedantic -Wall -O3 -c -o ../lib/CPUTimer.o ../lib/CPUTimer.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o ../lib/AvlTree.o ../lib/AvlTree.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o ../lib/keypair.o ../lib/keypair.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o graph.o graph.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -c -o dijkstra.o dijkstra.cpp -I. -I../lib 
g++ -pedantic -Wall -O3 -o ../../q1 ../lib/CPUTimer.o ../lib/AvlTree.o ../lib/keypair.o graph.o dijkstra.o questao1.cpp -I. -I../lib 
dijkstra.o: In function 'Dijkstra::executeAvl(int)':
dijkstra.cpp:(.text+0x25d): undefined reference to 'AvlTree<KeyPair, std::less<KeyPair>, nil<KeyPair> >::AvlTree()'
(... a lot of errors like above ...)
collect2: ld returned 1 exit status
make[1]: ** [q1] Erro 1

我在这里做错了什么?

c++ compiler-errors avl-tree
1个回答
2
投票

假设AvlTree.h声明了一个模板类

AvlTree<>
,AvlTree.cpp定义了实现:

您不能在单独的翻译单元 (.cpp) 中定义模板代码的实现——它必须存在于使用它的地方。 这就是为什么他们将其包含在标题中。 将实现放在要包含的 .cpp 文件中只是一种设计选择,以保持 .h 文件简洁。

(嗯,从技术上讲,您可以将模板定义放在单独的翻译单元中,但您必须为您将使用的模板参数显式实例化它。我猜这不是您想要做的。)

© www.soinside.com 2019 - 2024. All rights reserved.