Hey guys, new poster here. I'm rather desperate here, I just do not understand the concept of templates very well. I've used the search function, but I don't see the problem addressed in any other threads. Any help is much appreciated.

My assignment is to create a templated vector class using the following prototypes/definitions:
//I cannot modify these prototypes at all.

#ifndef _MYVECTOR
#define _MYVECTOR
#include <iostream>
using namespace std;

class BADINDEX{};

template <class T>
class containerInterface
{
    public:
        virtual containerInterface <T>& pushFront(T)  = 0;
        virtual containerInterface <T>& pushBack(T)   = 0;
        virtual containerInterface <T>& popFront(T&) throw(BADINDEX) = 0;
        virtual containerInterface <T>& popBack(T&)  throw(BADINDEX) = 0;
        virtual int getSize()      = 0;
        virtual bool isFull()      = 0;
        virtual bool isEmpty()     = 0;
        virtual T front()    throw(BADINDEX)   = 0;
        virtual T back()     throw(BADINDEX)   = 0;
        virtual T& operator[] (int) throw(BADINDEX)  = 0;
        virtual void erase()    throw(BADINDEX) = 0;
};

template <class T>
class myVector:public containerInterface<T>
{
    public:
        myVector();
        ~myVector();
        myVector(const myVector&);
        myVector <T>& operator=(myVector&);
        myVector <T>& pushFront(T);
        myVector <T>& pushBack (T);
        myVector <T>& popFront (T&)  throw(BADINDEX);
        myVector <T>& popBack  (T&)  throw(BADINDEX);
        T front()  throw(BADINDEX);
        T back()   throw(BADINDEX);
        T& operator[] (int) throw(BADINDEX);
        int getSize();
        bool isFull();
        bool isEmpty();
        void erase();

    private:
        T *data;
        int size;
        int capacity;
        void grow();
        void shiftRight();
        void shiftLeft();
};

I think I understand how to do it, and have written all the functions, but it will not compile, and I think my constructor, copy constructor, and destructor are the primary culprits, since they do not have a bracketed <T> as part of the function header. Here are the functions I've written:

myVector::myVector()
{
    size = 0;
    capacity = 10;

    data = new T [capacity];

}

myVector::~myVector()
{
    delete [] data;
}

myVector::myVector(const myVector& other)
{
    size = other.size;
    capacity = other.capacity;

    data = new T [capacity];

    for(int i = 0; i < size; i++)
    {
        data[i] = other.data[i];
    }
}

myVector<T>& myVector::operator=(myVector& other)
{
    if(data != other.data)
    {
        delete[] data;
        size = other.size;
        capacity = other.capacity;

        data = new T [capacity];

        for(int i = 0; i < size; i++)
        {
            data[i] = other.data[i];
        }
    }

    return *this;
}

myVector<T>& myVector::pushFront(T n)
{
    shiftRight();
    data[0] = n;

    return *this;
}

myVector<T>& myVector::pushBack(T n)
{
    size++;
    grow();

    data[size] = n;

    return *this;
}

myVector<T>& myVector::popFront(T& n)
{
    n = data[0];

    shiftLeft();

    return *this;
}

myVector<T>& myVector::popBack(T& n)
{
    n = data[size];

    size--;

    return *this;
}

T front()
{
    return data[0];
}

T back()
{
    return data[size];
}

T& operator[](int n)
{
    return data[n];
}

int getSize()
{
    return size;
}

bool isFull()
{
    return (size == capacity);
}

bool isEmpty()
{
    bool answer = false;

    if(size == 0)
    {
        answer = true;
    }

    return answer;
}

void erase()
{
    delete []data;

    size = 0;
    capacity = 10;

    data = new T [capacity];
}

void grow()
{
    while(size >= capacity)
    {
        T* temp;
        temp = data;

        capacity *= 2;

        data = new T[capacity];

        for(int i = 0; i < size; i++)
        {
            data[i] = temp.data[i];
        }

        delete []temp;
    }

}

void shiftRight()
{
    size++;
    grow();

    for(int i = size; i > 0; i--)
    {
        data[i] = data[i - 1];
    }
}

void shiftLeft()
{
    size--;

    for(int i = 0; i < size; i++)
    {
        data[i] = data[i + 1];
    }
}

I get a compile error on the line of the constructor telling me that I can't use the template class myVector without template parameters. This makes sense, but I don't know how to fix it. Any help is appreciated. Thanks.

Recommended Answers

All 5 Replies

If you define a member function for a template class outside of the class definition, you need to recreate the template parameters:

template <typename T>
myVector<T>::myVector()
{
    size = 0;
    capacity = 10;

    data = new T [capacity];

}

template <typename T>
myVector<T>::~myVector()
{
    delete [] data;
}

Thanks, Narue, that was helpful. That solved most of my problems, and I figured out some of the exception handling issues that I had as well. I think something is still fundamentally wrong, as I am getting the following errors.

#ifndef _MYVECTOR
#define _MYVECTOR
#include <iostream>
using namespace std;

class BADINDEX{};

template <class T>
class containerInterface
{
    public:
        virtual containerInterface <T>& pushFront(T)  = 0;
        virtual containerInterface <T>& pushBack(T)   = 0;
        virtual containerInterface <T>& popFront(T&) throw(BADINDEX) = 0;
        virtual containerInterface <T>& popBack(T&)  throw(BADINDEX) = 0;
        virtual int getSize()      = 0;
        virtual bool isFull()      = 0;
        virtual bool isEmpty()     = 0;
        virtual T front()    throw(BADINDEX)   = 0;
        virtual T back()     throw(BADINDEX)   = 0;
        virtual T& operator[] (int) throw(BADINDEX)  = 0;
        virtual void erase()    = 0;
};

template <class T>
class myVector:public containerInterface<T>
{
    public:
        myVector();
        ~myVector();
        myVector(const myVector&);
        myVector <T>& operator=(myVector&);
        myVector <T>& pushFront(T);
        myVector <T>& pushBack (T);
        myVector <T>& popFront (T&)  throw(BADINDEX);
        myVector <T>& popBack  (T&)  throw(BADINDEX);
        T front()  throw(BADINDEX);
        T back()   throw(BADINDEX);
        T& operator[] (int) throw(BADINDEX);
        int getSize();
        bool isFull();
        bool isEmpty();
        void erase();

    private:
        T *data;
        int size;
        int capacity;
        void grow();
        void shiftRight();
        void shiftLeft();
};

template <class T>
myVector<T>::myVector()
{
    size = 0;
    capacity = 10;

    data = new T [capacity];

}

template <class T>
myVector<T>::~myVector()
{
    delete [] data;
}

template <class T>
myVector<T>::myVector(const myVector& other)
{
    size = other.size;
    capacity = other.capacity;

    data = new T [capacity];

    for(int i = 0; i < size; i++)
    {
        data[i] = other.data[i];
    }
}

template <class T>
myVector<T>& myVector<T>::operator=(myVector& other)
{
    if(data != other.data)
    {
        delete[] data;
        size = other.size;
        capacity = other.capacity;

        data = new T [capacity];

        for(int i = 0; i < size; i++)
        {
            data[i] = other.data[i];
        }
    }

    return *this;
}

template <class T>
myVector<T>& myVector<T>::pushFront(T n)
{
    shiftRight();
    data[0] = n;

    return *this;
}

template <class T>
myVector<T>& myVector<T>::pushBack(T n)
{
    size++;
    grow();

    data[size] = n;

    return *this;
}

template <class T>
myVector<T>& myVector<T>::popFront(T& n) throw(BADINDEX)
{
    if(size > 0)
    {
        n = data[0];

        shiftLeft();
    }
    else
    {
        throw BADINDEX();
    }
    return *this;
}

template <class T>
myVector<T>& myVector<T>::popBack(T& n) throw(BADINDEX)
{

    if(size > 0)
    {
        n = data[size];

        size--;
    }
    else
    {
        throw BADINDEX();
    }
    return *this;
}

template <class T>
T myVector<T>::front() throw(BADINDEX)
{
    if(size > 0)
    {
        return data[0];
    }
    else
    {
        throw BADINDEX();
    }
}

template <class T>
T myVector<T>::back() throw(BADINDEX)
{
    if(size > 0)
    {
        return data[size];
    }
    else
    {
        throw BADINDEX();
    }
}

template <class T>
T& myVector<T>::operator[](int n) throw(BADINDEX)
{
    if(n >= capacity || n < 0)
    {
        throw BADINDEX();
    }
    else
    {
        return data[n];
    }
}

template <class T>
int myVector<T>::getSize()
{
    return size;
}

template <class T>
bool myVector<T>::isFull()
{
    return (size == capacity);
}

template <class T>
bool myVector<T>::isEmpty()
{
    bool answer = false;

    if(size == 0)
    {
        answer = true;
    }

    return answer;
}

template <class T>
void myVector<T>::erase()
{
    delete []data;

    size = 0;
    capacity = 10;

    data = new T [capacity];
}

template <class T>
void myVector<T>::grow()
{
    while(size >= capacity)
    {
        T* temp;
        temp = data;

        capacity *= 2;

        data = new T[capacity];

        for(int i = 0; i < size; i++)
        {
            data[i] = temp.data[i];
        }

        delete []temp;
    }

}

template <class T>
void myVector<T>::shiftRight()
{
    size++;
    grow();

    for(int i = size; i > 0; i--)
    {
        data[i] = data[i - 1];
    }
}

template <class T>
void myVector<T>::shiftLeft()
{
    size--;

    for(int i = 0; i < size; i++)
    {
        data[i] = data[i + 1];
    }
}

#endif

I get the following errors:


What it refers to as line 127 is line 118 in what I've pasted here, and what it refers to as line 256 is line 247 here.


The line it is referring to in the driver is:

for(int i = 0; i < 10; i++)
                   v1.pushBack(i).pushFront(-i);


Please advise. Thanks again. I really have no idea what those errors mean.

what it actually does.
Let me tell you what it actually does, and what it should do
first what it does

template <class T>
void myVector<T>::grow(){    
   while(size >= capacity)    {        
        T* temp;        
        temp = data;         
        capacity *= 2;         
        data = new T[capacity];         
        for(int i = 0; i < size; i++)        
        {
             data[i] = temp.data[i];        
        }
         delete []temp;    
  }
}

basically T refers to int in your case now the new code becomes.

void myVector<int>::grow(){    
   while(size >= capacity)    {        
        int* temp;        
        temp = data;         
        capacity *= 2;         
        data = new int[capacity];         
        for(int i = 0; i < size; i++)        
        {
             data[i] = temp.data[i];        
        }
         delete []temp;    
  }
}

lets move from bottom up manner you'll recognise yourself.
what does your sentence data = temp.data means ???
int is a primitive type not a aggregate type, so a compile error is there.
now you know what should be change.

Yeah, I found that last night, thanks. temp is a pointer, not an object, so I just needed to change temp.data to temp and it worked.

I have some sort of small logic error with popback and popfront, but everything else works fine.

Thanks for your help.

Figured out my last logic error. Solved. Thanks!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.