- C++: “undefined reference to” templated class function 6
- Solutions
- Solution 1 : Explicitly instantiate the template
- Solution 2 : Move the implementation code into the header file
- Solution 3 : Move the implementation code into a new header file and include it in the original header file
- Undefined Reference to Class::Function() in C++
- Types of Errors in C++
- Undefined Reference to a Class::Function() in C++
- Resolve Undefined Reference to a Class::Function() Due to No Function Definition in C++
- Cpp undefined reference to class
- Cpp undefined reference to class
C++: “undefined reference to” templated class function 6
In case you have a project where you use a templated class that is split in its own header ( .h ) and source ( .cpp ) files, if you compile the class, into an object file ( .o ), separately from the code that uses it, you will get the undefined reference to error at linking.
Lets assume we have Stack.cpp and Stack.h which define a templated stack using vectors. And main.cpp that uses this class after including Stack.h .
If you try to compile these files as mentioned above, one by one, later you will get a linking error saying undefined reference to for the methods of the class.
The code in the template is not sufficient to instruct the compiler to produce the methods that are needed by main.cpp (e.g. Stack::push(. ) and Stack::push(. ) ) as the compiler does not know, while compiling Stack.cpp by itself, the data types it should provide support for.
The reason it allows you to compile these incomplete objects is the following:
- main.cpp : the compiler will implicitly instantiate the template classes Stack and Stack because those particular instantiations are requested in main.cpp . Since the implementations of those member functions are not in main.cpp , nor in any header file included in main.cpp (particularly Stack.h ), the compiler will not include complete versions of those functions in main.o and it will expect to find them in another object during linking.
- Stack.cpp : the compiler won’t compile the instantiations of Stack and Stack neither as there are no implicit or explicit instantiations of them in Stack.cpp nor Stack.h .
So in the end, neither of the .o files contain the actual implementations of Stack and Stack and the linking fails.
Solutions
Solution 1 : Explicitly instantiate the template
At the end of Stack.cpp , you can explicitly instantiate all needed templates.
In our example we would add:
template class Stack; template class Stack;
This will ensure that, when the compiler is compiling Stack.cpp that it will explicitly compile all the code needed for the Stack and Stack classes.
Using this method, you should ensure that all the of the implementation is placed into one .cpp file and that the explicit instantation is placed after the definition of all the functions (for example, at the end of the file).
A problem with this method is that it forces you to update the Stack.cpp file each time you want to add support for a new data type (or remove one).
Solution 2 : Move the implementation code into the header file
Move all the source code of Stack.cpp to Stack.h , and then delete Stack.cpp . Using this method you do not need to manually instantiate all possible data types that are needed and thus you do not need to modify code of the class. As a side-effect, if you use the header file in many other source files, it will compile the functions of the header file in each source. This can make compilation slower but it will not create any compilation/linking problems, as the linker will ignore the duplicate implementations.
Solution 3 : Move the implementation code into a new header file and include it in the original header file
Rename Stack.cpp to Stack_impl.h , and then include Stack_impl.h from Stack.h to keep the implementation in a separate file from the declaration. This method will behave exactly like Solution 2 .
Undefined Reference to Class::Function() in C++
- Types of Errors in C++
- Undefined Reference to a Class::Function() in C++
- Resolve Undefined Reference to a Class::Function() Due to No Function Definition in C++
- Resolve Undefined Reference to a Class::Function() Due to Not Linked Object Files in C++
- Resolve Undefined Reference to a Class::Function() Due to Not Compiled Dependent Files in C++
This tutorial briefly discusses one of the most common and equally critical errors in C++ programming (i.e., Undefined Reference to a Class::Function() ).
First, we will briefly discuss different errors while coding in C++. Then, we will explain the causes and fixes for the undefined reference error.
Types of Errors in C++
- Syntax Errors are the errors that occur due to violations in the rules of C++ or any syntaxes.
- Run-time Errors are the errors that occur when there is no programming issue syntactically but are detected at the time of execution and lead to a program crash.
- Logical Errors occur when we are not getting our desired results or output, which means there are mistakes in the logic of our program.
- Linker Errors are the type of errors when the program is compiled successfully and is trying to link some other objects with our main object file, and thus executable is not generated. For example, any wrong prototype of the function defined, any incorrect header file included, etc.
Undefined Reference to a Class::Function() in C++
This is the most frequently occurring error in C++ and is equally critical, especially for new programmers. This type of linker error can affect the running of the program.
These errors mainly occur when the program is compiled successfully and is at the linking phase trying to link other object files with the main object. There are some cases when the program gives some output, and this error occurs.
So, it is sometimes complicated to trace down and correct such errors.
Undefined Reference error occurs when we have used any reference to some class, function, or variable. The linker cannot find its definition in all the linked object files and libraries, thus generating the error Undefined Reference to a Class::Function() .
There can be several causes of these errors, but we will discuss some of them here.
Resolve Undefined Reference to a Class::Function() Due to No Function Definition in C++
This can be the most straightforward reason for this error, that you have provided the prototype of the function but forgot to give its definition.
Cpp undefined reference to class
Hello all. I have a basic understanding of c++. I am doing some learning by following along on some of the classes on MIT OCW, particularly Computer Graphics. Working on Assignment 0 where I inherit a bunch of header code and have to create main.cpp. I inherit several vector class files, which are complete, but am struggling to instantiate an object of the vector class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using namespace std; int main() < vectorThisWorks; float x = 0.1; float y = 0.2; float z = 0.3; Vector3f V(x,y,z); >
The Vector3f class looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
class Vector2f; class Vector3f < public: static const Vector3f ZERO; static const Vector3f UP; static const Vector3f RIGHT; static const Vector3f FORWARD; Vector3f( float f = 0.f ); Vector3f( float x, float y, float z ); Vector3f( const Vector2f& xy, float z ); Vector3f( float x, const Vector2f& yz ); // copy constructors Vector3f( const Vector3f& rv ); // assignment operators Vector3f& operator = ( const Vector3f& rv ); // no destructor necessary // returns the ith element const float& operator [] ( int i ) const; float& operator [] ( int i ); float& x(); float& y(); float& z(); float x() const; float y() const; float z() const; Vector2f xy() const; Vector2f xz() const; Vector2f yz() const; Vector3f xyz() const; Vector3f yzx() const; Vector3f zxy() const; float abs() const; float absSquared() const; void normalize(); Vector3f normalized() const; Vector2f homogenized() const; void negate(); // ---- Utility ---- operator const float* () const; // automatic type conversion for OpenGL operator float* (); // automatic type conversion for OpenGL void print() const; Vector3f& operator += ( const Vector3f& v ); Vector3f& operator -= ( const Vector3f& v ); Vector3f& operator *= ( float f ); static float dot( const Vector3f& v0, const Vector3f& v1 ); static Vector3f cross( const Vector3f& v0, const Vector3f& v1 ); // computes the linear interpolation between v0 and v1 by alpha \in [0,1] // returns v0 * ( 1 - alpha ) * v1 * alpha static Vector3f lerp( const Vector3f& v0, const Vector3f& v1, float alpha ); // computes the cubic catmull-rom interpolation between p0, p1, p2, p3 // by t \in [0,1]. Guarantees that at t = 0, the result is p0 and // at p1, the result is p2. static Vector3f cubicInterpolate( const Vector3f& p0, const Vector3f& p1, const Vector3f& p2, const Vector3f& p3, float t ); private: float m_elements[ 3 ]; >; // component-wise operators Vector3f operator + ( const Vector3f& v0, const Vector3f& v1 ); Vector3f operator - ( const Vector3f& v0, const Vector3f& v1 ); Vector3f operator * ( const Vector3f& v0, const Vector3f& v1 ); Vector3f operator / ( const Vector3f& v0, const Vector3f& v1 ); // unary negation Vector3f operator - ( const Vector3f& v ); // multiply and divide by scalar Vector3f operator * ( float f, const Vector3f& v ); Vector3f operator * ( const Vector3f& v, float f ); Vector3f operator / ( const Vector3f& v, float f ); bool operator == ( const Vector3f& v0, const Vector3f& v1 ); bool operator != ( const Vector3f& v0, const Vector3f& v1 ); // VECTOR_3F_H
My understanding is that there are multiple constructors for this class, one of them being:
Vector3f( float x, float y, float z );
I’ve seen answers to similar questions that say that the cause is that you did not link the header files properly, or you did not use the proper implementation. I’m not sure how Vector3f V(0.1, 0.2, 0.3) is not a proper implementation. I have added the location of the header file to the search directories in Code::blocks, so I don’t believe that is the problem.
Here is the compiler error:
D:/Coding/CG/Assignment0/TestVec/main.cpp:22: undefined reference to `Vector3f::Vector3f(float, float, float)’
Note that the compiler does not throw an error at the following line
I don’t fully understand that yet either. A necessary part of the assignment is to create a vector of Vector3f’s
Any advice would be appreciated! Sorry in advance if I’m missing something obvious and basic.
Here is the compiler error: D:/Coding/CG/Assignment0/TestVec/main.cpp:22: undefined reference to `Vector3f::Vector3f(float, float, float)’ |
Actually that is not compile error, it is a linker error. This error is telling you that the linker can’t find the implementation of that function. Did you write the code for that function and did you add that code to your project?
That is not a compiler error. It is a linker error.
It is telling you that you are trying to call Vector3f::Vector3f(float, float, float), but that you have no implementation for that function.
Since you are provided the header files, for vector3f, presumably you are also provided the object files for that library. You need to tell the code:blocks linker where to find the Vector3f library file (object, not header).
Thank you both. You’re absolutely correct. When organizing my project folder I had misplaced a set of very important files (the .cpp implementations for those header files). Appreciate your kind responses to such an amateur error.
Cpp undefined reference to class
Please tell me how to compile this code.
main.cpp and DerClass files are in different directories.
int main() < DerClass der1; der1.fn(); //undefined reference to `DerClass::fn()' >
class DerClass < public: void fn(); //this not compile //void fn() < std::cout //this works >;
void DerClass::fn() < std::cout " DerClass"; >
inherit/main.cpp inherit/lib/DerClass.h inherit/lib/DerClass.cpp
Maybe the g++ command is off:
C:\Users\wolf\Documents\demo_MinGW\inherit>g++ -Wall -Ilib main.cpp C:\Users\wolf\AppData\Local\Temp\cc6bIt03.o:main.cpp:(.text+0x15): undefined ref erence to `DerClass::fn()' collect2.exe: error: ld returned 1 exit status
Also note that it would be better to put them in the same directories so as to not have problems like these. But if you really want to, you can set your compiler to do that in your includes. For more info about how to do this, visit your IDE/compiler site and see how to ‘link’ them up(usually in this case, just search for how to include files in compiler name).
I changed the #include to quotes and moved all files into the same directory as you suggested.
Also removed the std::cout from the function, so that is no longer an issue.
Still getting the same error though.
int main() < DerClass der1; der1.fn(); //undefined reference to `DerClass::fn()' //compiles when this line is commented >
class DerClass < public: void fn(); >;
C:\Users\wolf\Documents\demo_MinGW\inherit>g++ -Wall main.cp p C:\Users\wolf\AppData\Local\Temp\ccKX706N.o:main.cpp:(.text+0x15): undefined ref erence to `DerClass::fn()' collect2.exe: error: ld returned 1 exit status
I think its your compiler. See to it that the compiler is properly set.Btw I’m using codeblocks and it works just fine. 🙂