C++ c+;中的头文件有问题+;:链接器命令失败

C++ c+;中的头文件有问题+;:链接器命令失败,c++,c++11,header-files,C++,C++11,Header Files,提前为我确定的事情道歉是一个非常简单的问题,但我一直无法找到解决办法。我正在将一个非常简单的C++项目放在一起,但是在适当地使用头文件时遇到了问题 目录结构如下: . ├── mainGraph │   └── hnsw.cpp └── utils ├── distances.cpp └── distances.h 距离头文件(distance.h): 现在,当我实际尝试使用以下命令编译hnsw.cpp时:g++hnsw.cpp--std=c++11我得到以下错误: Undef

提前为我确定的事情道歉是一个非常简单的问题,但我一直无法找到解决办法。我正在将一个非常简单的
C++
项目放在一起,但是在适当地使用头文件时遇到了问题

目录结构如下:

.
├── mainGraph
│   └── hnsw.cpp
└── utils
    ├── distances.cpp
    └── distances.h
距离头文件(
distance.h
):

现在,当我实际尝试使用以下命令编译
hnsw.cpp
时:
g++hnsw.cpp--std=c++11
我得到以下错误:

Undefined symbols for architecture x86_64:
  "distance(std::__1::vector<double, std::__1::allocator<double> > const&, std::__1::vector<double, std::__1::allocator<double> > const&, Metric)", referenced from:
      _main in hnsw-ad0e05.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
架构x86_64的未定义符号: “距离(标准::_1::向量常数和,标准::_1::向量常数和,度量)”,引用自: _hnsw-ad0e05.o中的干管 ld:找不到架构x86_64的符号 叮当声:错误:链接器命令失败,退出代码为1(使用-v查看调用)
如果我将main移到
distance.cpp
文件中,那么一切都会顺利进行。为了简洁起见,我不会发布整个文件,因为它是相当大的,而且我相当确定它不相关。如果这里有任何关于理解一般过程的资源,这也会非常有帮助。

如果您不想为以后的链接构建单个对象文件,而是一次构建整个可执行文件,则需要在命令行上指定所有参与的翻译单位:

g++ -std=c++11 hnsw.cpp ../utils/distances.cpp
输出文件将被称为
a.out
,除非您还使用
-o
标志覆盖该名称

通常,您会单独编译翻译单元,并在单独的步骤中链接它们:

g++-std=c++11 mainGraph/hnsw.cpp-c-o mainGraph/hnsw.o
g++-std=c++11 utils/distance.cpp-c-o utils/distance.o
g++-std=c++11 mainGraph.hnsw.o utils/distance.o-o myprog

您也不会手工维护这些命令,而是将它们粘贴到Makefile或一些等效的构建系统中。关键是,你不需要重新编译仅仅因为你改变了源代码的某部分而没有改变的翻译单元。

< P>当你运行<代码> G++HNSW.CPP——STD= C++ 11 时,你告诉编译器编译HNSW.CPP,并将输出与C++标准库链接起来,创建一个可执行文件。链接器无法找到距离的实现,因为它位于distance.cpp中

您需要编译这两个文件并将它们链接在一起。实现这一点的方法有很多,但最简单的方法是在调用gcc时指定两个源文件,如下所示:

g++ -std=c++11 hnsw.cpp ../utils/distances.cpp

这非常有用。事后看来似乎很明显,但什么不明显。最后一个问题是关于你第二篇文章的顺序。你在距离之前编译hnsw有什么原因吗?似乎相反的方式更有意义,因为hnsw需要距离。@SlaterTyranus:这两种方式不相关,可以按任何顺序编译,也可以并行编译(特别是当您有多个核时)。这正是
make
为您免费提供的功能。@SlaterTyranus:说清楚,两个翻译单元都不“需要”任何有意义的另一个。只有链接需要所有的翻译单元。(但是,两个转换单位都取决于文件距离.h,因此如果更改该文件,则需要重新生成两个TU。该文件构成两个TU的一部分。)完全有道理。谢谢下载。你有没有可能知道一些好的资源,让我更好地了解整个过程的后端?谢谢你的回答!遗憾的是,你在FGIW比赛中输给了305k代表:)
g++ -std=c++11 hnsw.cpp ../utils/distances.cpp
g++ -std=c++11 hnsw.cpp ../utils/distances.cpp