C ++ class template undefined function reference

I keep getting the undefined link when I call two functions from my template class β€œadd” and β€œmore” in my main function.

So I have: number.h

#ifndef NUMBER_H #define NUMBER_H template <class T> class number { public: T x; T y; number (int a, int b){ x=a; y=b;} int add (T&); T greater (); }; #endif 

number.cpp

 #include "number.h" template <class T> int number<T>::add (T& rezAdd){ rezAdd = x+y; return 1; } template <class T> T number<T>::greater (){ return x>y? x : y; } 

And my main file: resolver.cpp

 #include <stdio.h> #include <stdlib.h> #include "number.h" int main (int argc, char **argv) { int aux; number<int> c(3,5); c.add(aux); printf ("number added [%d]\n", c.add(aux)); printf ("greater number: [%d]\n", c.greater()); return 0; } 

The errors I get are the following:

 g++ -Wall -o tema1 resolver.cpp number.cpp /tmp/ccX483J4.o: In function `main': resolver.cpp:(.text+0x34): undefined reference to `number<int>::add(int&)' resolver.cpp:(.text+0x47): undefined reference to `number<int>::add(int&)' resolver.cpp:(.text+0x64): undefined reference to `number<int>::greater()' collect2: ld returned 1 exit status make: *** [all] Error 1 

Thanks for the help in advance!

+6
c ++ c undefined-reference class
source share
3 answers

Your class is named incorrect. Your class is named cai , where all your functions belong to a class named number : http://ideone.com/ZayX0c

One more thing .. you cannot have templates in a .cpp file. Template / patch functions are included in the header along with the class declaration. This is the cause of your undefined function error. Functions without templates are included in .cpp.

 #include <cstdio> #include <cstdlib> template <class T> class number { public: T x; T y; number (int a, int b){ x=a; y=b;} int add (T&); T greater (); }; template <class T> int number<T>::add (T& rezAdd){ rezAdd = x+y; return 1; } template <class T> T number<T>::greater (){ return x>y? x : y; } int main (int argc, char **argv) { int aux; number<int> c(3,5); c.add(aux); printf ("number added [%d]\n", c.add(aux)); printf ("greater number: [%d]\n", c.greater()); return 0; } 
+5
source share

I prefer having all of my functions in a .cpp file, whether they are template functions or regular functions. And there is a way to do this with some basic #ifndef magic. Here is what you can do:

main.cpp

 #include "myclass.hpp" int main() { // ... } 

myclass.hpp

 #ifndef MYCLASS #define MYCLASS template<class T> class MyClass { T val; public: MyClass(T val_); } #define MYCLASS_FUNCTIONS #include "myclass.cpp" #endif 

myclass.cpp

 #ifndef MYCLASS_FUNCTIONS #include "myclass.hpp" // regular functions: // ... #else // template functions: template<class T> MyClass<T>::MyClass(T val_) :val(val_) {} // ... #endif 

This is how the precompiler sees it. We have two .cpp files.

  • When we compile main.cpp, we:
    • enable myclass.hpp
    • check that MYCLASS undefined and this
    • identify him
    • provide the compiler with the definitions of the generated class (from the template class)
    • enable myclass.cpp
    • define MYCLASS_FUNCTIONS
    • check if MYCLASS_FUNCTIONS is MYCLASS_FUNCTIONS , this
    • provide the compiler with definitions of the generated functions (from the template functions)
  • When we compile myclass.cpp
    • check if MYCLASS_FUNCTIONS is MYCLASS_FUNCTIONS , it is not
    • enable myclass.hpp
    • check that MYCLASS undefined and this
    • identify him
    • provide class definitions to the compiler
    • enable myclass.cpp
    • enable myclass.hpp again
    • this time MYCLASS defined like this, do nothing inside, return to myclass.cpp
    • check if MYCLASS_FUNCTIONS is MYCLASS_FUNCTIONS , this
    • provide the compiler with a definition of the generated functions (from the template functions)
    • exit turns on twice
    • pass all regular functions to the compiler
+4
source share

Move the add and greater function template definitions to your number.h .

Remember that add and greater are not functions; they are functional patterns. To create the actual functions, the compiler must create an instance of the template for certain types, for example int , and it can only do this if it has access to the template definition at the point where it detects that the instance is needed.

When you compile number.cpp , the compiler has access to the template definitions, but it does not see any code requiring a specific instance (for example, number<int> ), so it does not generate instances.

When you compile resolver.cpp , the compiler sees that it needs to create these templates for the int type, but it cannot, because it does not have its own definitions. Thus, it generates "external links", basically, it notes that the linker is looking for these functions in some other object file.

As a result, function templates do not receive an instance in any object file - in one because the compiler did not know what it should, and in the other because it could not - therefore, when the linker searches for them (to allow these external links), they can't find them. That is why you get an error.

Moving the definitions of the template functions to the header makes them visible to the compiler when compiling main.cpp , so it can create these functions for the int type. For this reason, function templates should usually be defined in header files, not in .cpp files.

+3
source share

All Articles