Wednesday, June 26, 2019

c++ - "Undefined reference to class::function..." - am I linking incorrectly?



I'm working on this NeuralNet class:



class NeuralNet {
public:
// Public functions
private:
vectors vect; // Point-of-access for functions in class vectors
// Private functions

};


And I'm using this extremely simple 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


When g++ gets run to build the final executable, I get a lot of errors in the following form:




neuralnet.o: /path/to/neuralnet.cpp: line# : undefined reference to vectors::fn_name(args)



For example, I have defined a function:



template void fill_vec(vector&, int, double);



When I call this function I pass a variable declared with type vector for the first argument, and the linker reports undefined reference to void vectors::fill_vec(std::vector >&, int, double)



All calls to functions of class vectors in the implementation of NeuralNet are called from vect. However, both neuralnet.cpp and neuralnet.h contain includes for "vectors.h", so I'm assuming that I'm somehow linking incorrectly.




Does anyone see anything obvious?


Answer



Unless you've defined fn_name() in-line in vectors.h, merely including that header from neuralnet.cpp and neuralnet.h is not sufficient. Make sure you can actually point your finger at that function body. You probably intended for it to be in vectors.cpp.



Being a template changes everything. You should define the template methods in the header file, not in the .cpp file. Although you might define fill_vec in your source file, the compiler doesn't actually instantiate it for any values of T because within that translation unit, it doesn't need any instantiations. You could manually instantiate it for every value of T you'll need, but it's easier to just define the function in the header at the same place you declare it. That way, the compiler has the definition available every place it's needed. You'll get multiple instantiations (one for each translation unit that uses it), but the linker knows how to consolidate those.



See also Undefined reference error for template method.


No comments:

Post a Comment

plot explanation - Why did Peaches' mom hang on the tree? - Movies & TV

In the middle of the movie Ice Age: Continental Drift Peaches' mom asked Peaches to go to sleep. Then, she hung on the tree. This parti...