Quasar
Quasar

Reputation: 551

Elementary data structures using generic programming

I am learning C++ and as a program minimum wish to build a few elementary data structures(arrays, vectors, lists, stacks, queues, matrices etcetera) using generic programming. Now, while classes for data containers are already defined in the C++ STL, I would like to learn by coding simple containers of my own.

To that end, I created QPArray class. QPArray data objects are fixed sized arrays. QPStack should accept any data container, that will be the home of the stack. Just like in STL.

I have tested QPArray and the code works well for integers.

1) I was searching the internet to see, how I could list initialize my own QPArray like below. However, I was unable to find any references.

QPArray<int,5> arr= {2,3,5,7,8};

Any tips or links would be immmensely helpful.

2) I tried to create a QPArray of std::string's. I tried printing the one of the elements to the console, but the correct version of the operator << () could not be found. I am under the assumption, that << is overloaded to work with std::string objects as arguments. Would anyone know, why this fails?

TestQPArray.cpp

QPArray<std::string, 7> arr1;
arr1[0] = "C++";
arr1[1] = "for";
arr1[2] = "quantitative";
arr1[3] = "finance";
arr1[4] = "is";
arr1[5] = "absolutely";
arr1[6] = "awesome";

std::cout << arr1.at(3) << std::endl;//Compile error

I apologize for posting the entire list QPArray.h, but it's need for completeness.

QPArray.h

#ifndef QPARRAY_H
#define QPARRAY_H
#include <cstring>

template <class T, std::size_t N>
class QPArray
{
private:
    T* items;
    int maxsize;
public:
    /*Constructors and destructors*/
    QPArray();
    QPArray(const T value);
    QPArray(const QPArray<T, N>& a);
    virtual ~QPArray();

    /* Overload = operator*/
    QPArray<T, N>& operator =(const QPArray<T, N>& a);

    /* Selectors - Element access*/
    T& at(int index);
    T& operator [](int index);
    T& front();
    T& back();

    /* Capacity*/
    bool empty();
    virtual int size();
    virtual int max_size();

    /*Operations*/
    QPArray<T, N>& fill(T value);
};

template <class T,std::size_t N>
QPArray<T, N>::QPArray()
{
    if (N > 0)
    {
        items = new T[N];
    }
    maxsize = N;
}

template <class T, std::size_t N>
QPArray<T, N>::QPArray(T value)
{
    maxsize = N;

    if (N > 0)
    {
        items = new T[N];
        for (int i = 0; i < maxsize; i++)
        {
            items[i] = value;
        }
    }
}

template <class T, std::size_t N>
QPArray<T,N>::QPArray(const QPArray<T, N>& a)
{
    maxsize = a.maxsize;
    items = new T[maxsize];
    for (int i = 0; i < maxsize; i++)
        items[i] = a.items[i];
}

template<class T, std::size_t N>
QPArray<T, N>::~QPArray()
{
    if(N > 0)
        delete[] items;
}

template<class T, std::size_t N>
QPArray<T, N>& QPArray<T, N>::operator =(const QPArray<T, N>& a)
{
    if (this == &a)
        return *this;

    if (maxsize != a.maxsize)
        throw std::runtime_error(std::string("Src and target array bounds do not match"));

    for (int i = 0; i < maxsize; i++)
    {
        items[i] = a.items[i];
    }

    return *this;
}

template <class T, std::size_t N>
T& QPArray<T, N>::at(int i)
{
    return items[i];
}

template <class T, std::size_t N>
T& QPArray<T, N>::operator [](int index)
{
    return items[index];
}

//Access the first element of the array
template <class T, size_t N>
T& QPArray<T, N>::front() {
    return items[0];
}

//Access the last element of the array 
template <class T, std::size_t N>
T& QPArray<T, N>::back() {
    return items[maxsize - 1];
}

template <class T, std::size_t N>
bool QPArray<T, N>::empty()
{
    if (maxsize == 0)
        return true;
    else
        return false;
}

template <class T, std::size_t N>
int QPArray<T,N>::size()
{
    return maxsize;
}

template <class T, std::size_t N>
int QPArray<T, N>::max_size()
{
    return maxsize;
}

template <class T, std::size_t N>
QPArray<T, N>& QPArray<T, N>::fill(T value)
{
    for (int i = 0; i < maxsize; i++)
    {
        items[i] = value;
    }

    return *this;
}

#endif // !ARRAY_H

Upvotes: 1

Views: 96

Answers (1)

artona
artona

Reputation: 1282

Ad 1 Try with std::initializer_list. It enables the container to assigned a {a, b, c, d} to the constructed variable.

For example

template <class T, std::size_t N>
QPArray<T,N>::QPArray(std::initializer_list<T> v)
{
    maxsize = v.size();
    items = new T[maxsize];
    int i = 0;
    for (auto & elem: v) 
        items[i++] = elem;
}

Ad 2 You haven't included string library in the file, as @Bo Persson indicated.

Upvotes: 2

Related Questions