0

I'm learning about template and i cant compile this code. The error is "undefined reference to `SimpleVector::SimpleVector(int)'" (and all other thing related to SimpleVector in main.cpp have this error). If i put all the code of cpp file in the header file, it still works, and i'm sure they're in the same directory.

SimpleVector.h file:

#ifndef SIMPLEVECTOR_H_INCLUDED
#define SIMPLEVECTOR_H_INCLUDED

template <class T>
class SimpleVector
{
private:
    T *aptr;
    int arraySize;
    void memError();
    void subError();
public:
    SimpleVector()
    {
        aptr = 0;
        arraySize = 0;
    }

    SimpleVector(int);

    SimpleVector(const SimpleVector &);

    ~SimpleVector();

    int size() const
    {
        return arraySize;
    }

    T getElementAt(int position);

    T &operator[](const int &);

    void push_back(T);

    void pop_back();
};

#endif // SIMPLEVECTOR_H_INCLUDED

SimpleVector.cpp file:

#include "SimpleVector.h"
#include <iostream>
#include <new>
#include <cstdlib>

using namespace std;

template <class T>
SimpleVector<T>::SimpleVector(int s)
{
    arraySize = s;
    try
    {
        aptr = new T [s];
    }
    catch (bad_alloc)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = 0;
    }
}

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
    arraySize = obj.arraySize;
    aptr = new T [arraySize];
    if (aptr == 0) memError();

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = *(obj.aptr + count);
    }
}

template <class T>
SimpleVector<T>::~SimpleVector()
{
    if (arraySize > 0)
        delete [] aptr;
}

template <class T>
void SimpleVector<T>::memError()
{
    cout << "ERROR: Cannot allocate memory.\n";
    exit(EXIT_FAILURE);
}

template <class T>
void SimpleVector<T>::subError()
{
    cout << "ERROR: Subcript out of range.\n";
    exit(EXIT_FAILURE);
}

template <class T>
T SimpleVector<T>::getElementAt(int sub)
{
    if (sub < 0 || sub >= arraySize)
        subError();
    return aptr[sub];
}
template <class T>
T &SimpleVector<T>::operator[](const int &sub)
{
    if (sub < 0 || sub >= arraySize)
        subError();
    return aptr[sub];
}

template <class T>
void SimpleVector<T>::push_back(T num)
{
    T *temp;
    temp = new T [arraySize];
    for (int count = 0; count < arraySize; count ++)
        temp[count] = aptr[count];
    delete [] aptr;
    arraySize += 1;
    aptr = new T [arraySize];
    for (int i = 0; i < arraySize; i++)
    {
        aptr[i] = temp[i];
    }
    aptr[arraySize-1] = num;
    delete [] temp;
}

template <class T>
void SimpleVector<T>::pop_back()
{
    T *temp;
    temp = new T [arraySize];
    for (int count = 0; count < arraySize; count ++)
        temp[count] = aptr[count];
    delete [] aptr;
    arraySize -= 1;
    aptr = new T [arraySize];
    for (int i = 0; i < arraySize; i++)
    {
        aptr[i] = temp[i];
    }
    delete [] temp;
}

     

main.cpp file:

#include <iostream>
#include "SimpleVector.h"
using namespace std;

int main()
{
    const int SIZE = 10;
    int count;

    SimpleVector<int> intTable(SIZE);

    SimpleVector<double> doubleTable(SIZE);

    for (count = 0; count < SIZE; count ++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
    }

    cout << "These values are in intTable: \n";
    for (count = 0; count < SIZE; count ++)
        cout << intTable[count] << " ";
    cout << endl;
    cout << "These values are in doubleTable: \n";
    for (count = 0; count < SIZE; count ++)
        cout << doubleTable[count] << " ";
    cout << endl;

    cout << "\nPop_back intTable and doubleTable.\n";
    intTable.pop_back();
    doubleTable.pop_back();

    cout << "These values are in intTable: \n";
    for (count = 0; count < intTable.size(); count ++)
        cout << intTable[count] << " ";
    cout << endl;
    cout << "These values are in doubleTable: \n";
    for (count = 0; count < doubleTable.size(); count ++)
        cout << doubleTable[count] << " ";
    cout << endl;

    cout << "\nPush_back intTable and doubleTable.\n";
    intTable.push_back(18);
    doubleTable.push_back(9*2.14);

    cout << "These values are in intTable: \n";
    for (count = 0; count < intTable.size(); count ++)
        cout << intTable[count] << " ";
    cout << endl;
    cout << "These values are in doubleTable: \n";
    for (count = 0; count < doubleTable.size(); count ++)
        cout << doubleTable[count] << " ";
    cout << endl;

    return 0;
}
MikeCAT
  • 69,090
  • 10
  • 44
  • 65
  • I see you are trying to do the "right" thing by putting the implemenation in its own `.cpp` file, but that doesn't work for templates. Roughly speaking, the compiler needs to see everything about the template when you use it, to be able to fully replace the `T` with `int` (or whatever type you choose). – BoBTFish Jul 08 '21 at 10:45

0 Answers0