I'm facing one linking related issue when writing some C++ code. When I declare a functor in header file ("class.h") and define in its source file ("class.cpp"), then try to use it in the main()
function, the compiler (Clang 12) shows "undefined reference". But when I add another usage to the source file ("class.cpp"), the issue is gone.
So my question is: how this issue got solved by adding another usage of functor in source file?
Any advice appreciated!
Update of question
Thanks for the comments from Patrik and Eng. And the here is the link to the question that I've already read: Why can templates only be implemented in the header file?.
The code I provided are extracted from some code similar to the "Alternative solution" provided by Luc Touraille, which is the highest voted answer at this moment. And to be more specific, my question is about how:
Increase inc;
traverse(inc);
These two lines (in the source file "class.cpp") solved the issue. And I think implementing the function traverse()
in header file can solve the "undefined reference" issue but cannot explain why the two lines work.
Sorry I'm quite new to compiler and linker, and I did made some searches about how they produce the compiled program. But unfortunately I haven't got a clue or proper understanding.
Source code below
class.h
#include <vector>
struct Increase {
void operator()(int &);
};
class MyVector {
public:
MyVector() ;
template<typename V>
void traverse(V &);
private:
std::vector<int> _elems;
};
class.cpp
#include "class.h"
void Increase::operator()(int &a) {
a++;
}
MyVector::MyVector() {
_elems.push_back(1);
_elems.push_back(2);
_elems.push_back(3);
_elems.push_back(4);
// Just provide a usage for Increase and traverse.
// Commenting the following two lines, the "undefined reference" error will appear.
// Uncommenting them will solve the issue.
// Increase inc;
// traverse(inc);
}
template<typename V>
void MyVector::traverse(V &v) {
for (int i = 0; i < _elems.size(); i++) {
v(_elems[i]);
}
}
main.cpp
#include "class.h"
int main() {
MyVector v;
Increase inc;
v.traverse(inc);
return 0;
}