tags:

views:

40

answers:

2

I found this vector template class implementation, but it doesn't compile on XCode.

Header file:

// File: myvector.h

#ifndef _myvector_h
#define _myvector_h

template <typename ElemType>
class MyVector
{
public:
    MyVector();
~MyVector();
int size();
void add(ElemType s);
ElemType getAt(int index);

private:
ElemType *arr;
int numUsed, numAllocated;
void doubleCapacity();
};

#include "myvector.cpp"

#endif

Implementation file:

// File: myvector.cpp

#include <iostream>
#include "myvector.h"

template <typename ElemType>
MyVector<ElemType>::MyVector()
{   
arr = new ElemType[2];
numAllocated = 2;
numUsed = 0;
}

template <typename ElemType>
MyVector<ElemType>::~MyVector()
{
delete[] arr;
}

template <typename ElemType>
int MyVector<ElemType>::size()
{
return numUsed;
}

template <typename ElemType>
ElemType MyVector<ElemType>::getAt(int index)
{
if (index < 0 || index >= size()) {
    std::cerr << "Out of Bounds";
    abort();
}
return arr[index];
}

template <typename ElemType>
void MyVector<ElemType>::add(ElemType s)
{
if (numUsed == numAllocated)
    doubleCapacity();
arr[numUsed++] = s;
}

template <typename ElemType>
void MyVector<ElemType>::doubleCapacity()
{
ElemType *bigger = new ElemType[numAllocated*2];
for (int i = 0; i < numUsed; i++)
    bigger[i] = arr[i];
delete[] arr;
arr = bigger;
numAllocated*= 2;
}

If I try to compile as is, I get the following error: "Redefinition of 'MyVector::MyVector()'" The same error is displayed for every member function (.cpp file).

In order to fix this, I removed the '#include "myvector.h"' on the .cpp file, but now I get a new error: "Expected constructor, destructor, or type conversion before '<' token". A similar error is displayed for every member as well.

Interestingly enough, if I move all the .cpp code to the header file, it compiles fine. Does that mean I can't implement template classes in separate files?

A: 

First, you have

 #include "myvector.cpp"

which creates a circular reference between the files. Just get rid of it.

The other problem is that you are defining a template class inside a .cpp file. Template definitions are only allowed inside header files. There may be ways around that, but for g++ (which XCode uses) that's how the cookie crumbles.

Tim
It's not that they're not *allowed* inside a .cpp file. There are just issues with compiling and linking if it's done that way that are inherent to how templates work (and the lack of decent support of the `export` keyword).
Pieter
A: 

It's always a good idea to place your templates in a header file. That way you don't mess up the linker with multiple definitions of the same instantiations and such.

And of course there's the circular inclusion :).

Pieter