-1

File main2.cpp:

#include "poly2.h"

int main(){
 Poly<int> cze;
 return 0;
}

File poly2.h:

template <class T>
class Poly {
public:
 Poly();
};

File poly2.cpp:

#include "poly2.h"

template<class T>
Poly<T>::Poly() {
}

Error during compilation:

src$ g++ poly2.cpp main2.cpp -o poly
/tmp/ccXvKH3H.o: In function `main':
main2.cpp:(.text+0x11): undefined reference to `Poly<int>::Poly()'
collect2: ld returned 1 exit status

I'm trying to compile above code, but there are errors during compilation. What should be fixed to compile constructor with template parameter?

Kev
  • 118,037
  • 53
  • 300
  • 385
scdmb
  • 15,091
  • 21
  • 85
  • 128

4 Answers4

4

The full template code must appear in one file. You cannot separate interface and implementation between multiple files like you would with a normal class. To get around this, many people write the class definition in a header and the implementation in another file, and include the implementation at the bottom of the header file. For example:

Blah.h:

#ifndef BLAH_H
#define BLAH_H

template<typename T>
class Blah {
    void something();
};

#include "Blah.template"

#endif

Blah.template:

template<typename T>
Blah<T>::something() { }

And the preprocessor will do the equivalent of a copy-paste of the contents of Blah.template into the Blah.h header, and everything will be in one file by the time the compiler sees it, and everyone's happy.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
1

If you use templates in C++, all implementations of functions that use templates need to be inside your header file. Or your compiler can't find the right (or any) version for a type.

See this questions for details.

Community
  • 1
  • 1
Fox32
  • 13,126
  • 9
  • 50
  • 71
1

The age old question of how do I define my template classes. A template isn't actually code, it is a template that you use to define code later. So, there are two possible solutions, if you know that there are only certain types of Poly that you are going to use, you can define them in the .cpp file.

#include "poly2.h"
Poly<int>;

template<class T>
Poly<T>::Poly() {
}

Or you can put all of the template definitions and declarations inside your header file. What I like to do is create a separate .hpp file and put the definitions in there. So I would do this:

poly2.h

template <class T>
class Poly {
public:
 Poly();
};
#include "poly2-impl.hpp"

poly2-impl.hpp

template<class T>
Poly<T>::Poly() {
}

And the thing about templates is that you can include the header file in multiple translation files without previously defined errors.

See here for more information: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

norcalli
  • 1,215
  • 2
  • 11
  • 22
0

Usually, all you need to compile a source file is a bunch of function declarations, and you can link in the definitions later.

Unfortunately it's not quite that simple when templates come into the mix. Because templates must be instantiated when used, their definitions must be visible when used. main2.cpp cannot see the definition of Poly<int>::Poly(), so this function is not instantiated. It is thus missing from the object file and not linkable.

You should write function templates in header files so that they are available in all Translation Units in which you use them. It's not ideal, but without export (or performing explicit instantiation), there's not a whole lot you can do about it.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055