C++ &引用;对类::函数的未定义引用…“-我链接错误吗?

C++ &引用;对类::函数的未定义引用…“-我链接错误吗?,c++,header,linker,include,makefile,C++,Header,Linker,Include,Makefile,我正在学习NeuralNet课程: class NeuralNet { public: // Public functions private: vectors vect; // Point-of-access for functions in class vectors // Private functions }; 我使用的是一个非常简单的makefile: all: nnet.exe nnet.exe: main.o neuralnet.o vectors.o

我正在学习NeuralNet课程:

class NeuralNet {
public:
    // Public functions
private:
    vectors vect; // Point-of-access for functions in class vectors
    // Private functions
};
我使用的是一个非常简单的makefile:

all: nnet.exe
nnet.exe: main.o neuralnet.o vectors.o
    g++ -o nnet.exe main.o vectors.o neuralnet.o
main.o: main.cpp neuralnet.h
    g++ -ggdb -c main.cpp
vectors.o: vectors.cpp vectors.h
    g++ -ggdb -c vectors.cpp
neuralnet.o: neuralnet.cpp neuralnet.h vectors.h
    g++ -ggdb -c neuralnet.cpp
clean:
    rm -f *.o nnet.exe
当运行g++来构建最终的可执行文件时,我得到以下形式的大量错误:

neuralnet.o:/path/to/neuralnet.cpp:line#:对向量的未定义引用::fn_名称(args)

例如,我定义了一个函数:

template void fill_vec(向量和,整数,双精度)

当我调用这个函数时,我传递一个变量,第一个参数的类型是
vector
,链接器报告
对void vectors::fill_vec(std::vector&,int,double)的未定义引用

NeuralNet
的实现中,对
类向量
函数的所有调用都是从
vect
调用的。然而,neuralnet.cpp和neuralnet.h都包含“vectors.h”的include,所以我假设我的链接不正确

有人看到任何明显的东西吗?

除非您在vectors.h中定义了
fn_name()
内联,仅包含来自neuralnet.cpp和neuralnet.h的标题是不够的。确保你能把手指指向功能体。您可能希望它位于vectors.cpp中

作为模板会改变一切。您应该在头文件中定义模板方法,而不是在.cpp文件中。虽然您可以在源文件中定义
fill\u vec
,但编译器实际上并不为
t
的任何值实例化它,因为在该翻译单元中,它不需要任何实例化。您可以为所需的
T
的每个值手动实例化它,但只需在声明函数的同一位置在标题中定义函数就更容易了。这样,编译器就可以在任何需要的地方使用定义。您将得到多个实例化(每个使用它的翻译单元一个),但是链接器知道如何合并这些实例化


另请参见。

neuralnet.h中是否包含vectors.h?是的,neuralnet标头也包含vectors.h。编辑问题以反映现在。这听起来很愚蠢-fn_name()(区分大小写)使用正确,对吗?发生此错误后,您不会收到“候选者是…”消息或其他任何消息,您知道吗?顺便说一下,这不是一个链接问题。
g++-c
参数会在最后一步之前删除链接。@RageD,g++提到的文件名是一个.o文件,错误消息是“未定义的引用”-这肯定是链接问题。@RageD-不,没有任何关于候选函数的消息。另外,问题是,当使用g++从目标文件构建最终可执行文件时,即应该发生链接时,会发生错误。错误消息中出现的
fn_name()
的变体都在vectors.cpp中定义,当然也包括向量。h——当你说把我的手指指向函数体时,你是什么意思?我的意思是你应该确保你能找到链接器说缺少的变量。函数的零参数版本真的定义了吗?它定义在哪一行?我假设链接器说的是实话,而函数并没有真正定义。如果你认为它是有定义的,证明它。如果你不能用手指着它说,“这就是它定义的地方”,那么它就没有定义。还要确保没有任何可能导致编译器跳过该函数的
ifdef
指令。