-1

I've read this page Why can templates only be implemented in the header file? but it's about a template class. And the constructor takes same type as class (if class is < int >, constructor also takes int, and so on). But I have simple (non-template) class. Sorry for duplication, please explain what should I do in this case?

I have a class 'Object' with field 'double d' and I want to make a template constructor. If I realize it inside the class, all works good, but if move the realisation outside of the class (from .h to .cpp), it doesn't work. Here's my code:

Object.h

class Object {
    double d;
public:
    template <class T> Object(T t);
};

Object.cpp

#include "Object.h"

template <class T> Object::Object(T t) {
    d = t;
}

main.cpp

#include "Object.h"

int main() {
    int a = 5;
    Object x(a);
    float b = 2.5;
    Object y(b);
    return 0;
}

Error appears in main.cpp in lines that creates x and y, there are:

undefined reference to `Object::Object<int>(int)'
undefined reference to `Object::Object<float>(float)'
Community
  • 1
  • 1
Pavel
  • 5,374
  • 4
  • 30
  • 55
  • 1
    100% duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – ForceBru Apr 10 '16 at 19:55

2 Answers2

1

Get rid of Object.cpp and move its contents to a header file.

When the compiler deals with Object.cpp, it doesn't generate any byte code because there are only some templates. When it encounters a 'mention' of Object::Object<int>(int) in your code, it goes to the header file, deduces the template parameters and successfully compiles everything.

The linker, however, isn't happy. It sees a call to Object::Object<int>(int), but can't find byte code for this method and raises an error.

Otherwise, you can define template <class T> Object::Object(T t) in main, but that's not so good and may lead to confusion.

ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • About adding "template class Object; template class Object; " at the beginning of main.cpp - it doesn't work because I have non-template class (not "template Object", but simple "class Object"). – Pavel Apr 10 '16 at 20:14
  • So it's remaining one question - is it a good tone to write the realisation of constructor inside the interface? – Pavel Apr 10 '16 at 20:16
  • @Pavel, if this constructor isn't very long, then it's OK – ForceBru Apr 10 '16 at 20:17
  • If I understand right, interface needs to show user which methods he can use – Pavel Apr 10 '16 at 20:18
  • @Pavel, that's why they're called _interfaces_ – ForceBru Apr 10 '16 at 20:22
0

You must implement all templates you want to use in the header file. If you only implement them in the .cpp file, only that .cpp file can see it.

kmdreko
  • 42,554
  • 6
  • 57
  • 106