0

So, I've created a basic VC++ program, and created a template class with 1 method (besides the constructor and destructor). I'm getting the following errors:

>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::~Vector<int>(void)" (??1?$Vector@H@@QAE@XZ) referenced in function _main
>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::Vector<int>(int)" (??0?$Vector@H@@QAE@H@Z) referenced in function _main
>c:\users\edy\documents\visual studio 2010\Projects\ex01\Debug\ex01.exe : fatal error LNK1120: 2 unresolved externals

Here is my code:

(CPP Class file)

using namespace std;
#include "Vector.h"
template <class T> Vector<T>::Vector(int n)
{
    this.crt = 0;
    this.dim = n;
    this.elem = new T[100];
}

template <class T> void Vector<T>::add(T e)
{
    this.elem[crt] = e;
    this.crt++;
}

template <class T> Vector<T>::~Vector(void)
{
    this.crt = 0;
}

(H Class file)

#pragma once
template <class T> class Vector
{
    public:
        int dim;
        T* elem;

        Vector(int n);
        void add(T e);
        ~Vector(void);

    private:
        int crt;
};

(Main file)

using namespace std;
#include "Vector.h"

int main(void)
{
    Vector<int> x(5);
    //x.add(1);    <--- if i decomment this line, it throws an additional error
    return 0;
}

Most solutions involved not implemented methods, but I have all my methods implemented. I have no idea what could be wrong. Any help?

Eduard Luca
  • 6,514
  • 16
  • 85
  • 137
  • possible duplicate of [Why should the implementation and the declaration of a template class be in the same header file?](http://stackoverflow.com/questions/3749099/why-should-the-implementation-and-the-declaration-of-a-template-class-be-in-the) – Bo Persson Jun 18 '12 at 21:54
  • @BoPersson how could i have known that you aren't allowed to do that? i've looked over the internet and found no such thing. – Eduard Luca Jun 18 '12 at 21:59
  • @BoPersson I disagree. There are questions that say that you can't have template classes in a separate file, but there aren't any questions that say that my error is caused by that. – Eduard Luca Jun 19 '12 at 09:37
  • Ok, try this question [C++ keep getting error LNK2019 unresolved external symbol](http://stackoverflow.com/questions/10271796/c-keep-getting-error-lnk2019-unresolved-external-symbol?rq=1) – Bo Persson Jun 19 '12 at 11:14
  • OK, then report my question as a duplicate of THAT question. – Eduard Luca Jun 19 '12 at 17:50

2 Answers2

5

Template class implementation need to be visible to all translation units that use them. Move the implementations to the header file.

Before you ask - no, there's no way to hide them, unless you know in advance which specializations for the class you have. If you want your Vector to be generic, the implementations need to be visible.

If you want to separate them, to usual way to go about it is to have the implementations in a .impl file which you include in the header.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
1

If you intend to implement the template in a .cpp file, you will need to provide an explicit instantiation of the template there as well. You can add to the template's .cpp file:

class template Vector<int>;

at the bottom. This will instantiate an int version of your vector template. But, you will find your template easier to use if you follow Luchian's advice. If you do as he suggests, the compiler will create the instantiations on demand for you as you use Vector<> on different types. If you leave it in a .cpp file, you will have to add an explicit instantiation each time you want to create a different kind of Vector<>.

Some think explicit instantiation is "leaner" than implicit, because if different sets of object files use the same template instantiations many times, the compiler may be creating just as many instantiations. However, the linker will remove the duplicate instantiations in the end when the executable is linked together. Even so, the bloat still persists if multiple shared libraries have reused the same template with the same parameters, even though the dynamic linker will clean it up. If executable loading time is important, this may be a reason to prefer explicit instantiation. If you have a very large project, and build and link times are an issue, this may also be a reason to prefer explicit instantiation.

Otherwise, you should stick with implicit instantiation.

jxh
  • 69,070
  • 8
  • 110
  • 193