Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending std::list

I need to use lists for my program and needed to decide if I use std::vector or std::list. The problem with vector is that there is no remove method and with list that there is no operator []. So I decided to write my own class extending std::list and overloading the [] operator.

My code looks like this:

#include <list>

template <class T >
class myList : public std::list<T>
{
public:
T operator[](int index);
T operator[](int & index);
myList(void);
~myList(void);
};

#include "myList.h"

template<class T>
myList<T>::myList(void): std::list<T>() {}

template<class T>
myList<T>::~myList(void)
{
std::list<T>::~list();
}

template<class T>
T myList<T>::operator[](int index) {
int count = 0;
std::list<T>::iterator itr = this->begin();
while(count != index)itr++;
return *itr;    
}

template<class T>
T myList<T>::operator[](int & index) {
int count = 0;
std::list<T>::iterator itr = this->begin();
while(count != index)itr++;
return *itr;
}

I can compile it but I get a linker error if I try to use it. Any ideas?

like image 940
Alexander Stolz Avatar asked Dec 14 '08 11:12

Alexander Stolz


4 Answers

Depending on your needs, you should use std::vector (if you need often appends/removes at the end, and random access), or std::deque (if you need often appends/removes at the end or at the beginning, and your dataset is huge, and still want random access). Here is a good picture showing you how to make the decision:

Container Choice
(source: adrinael.net)

like image 126
Johannes Schaub - litb Avatar answered Nov 19 '22 11:11

Johannes Schaub - litb


Given your original problem statement,

I need to use lists for my program and needed to decide if I use std::vector or std::list. The problem with vector is that there is no remove method and with list that there is no operator [].

there is no need to create your own list class (this is not a wise design choice anyway, because std::list does not have a virtual destructor, which is a strong indication that it is not intended to be used as a base class).

You can still achieve what you want using std::vector and the std::remove function. If v is a std::vector<T>, then to remove the value value, you can simply write:

#include <vector>
#include <algorithm>
T value = ...; // whatever
v.erase(std::remove(v.begin(), v.end(), value), v.end());
like image 26
ChrisN Avatar answered Nov 19 '22 12:11

ChrisN


All template code should be put in header file. This fill fix linking problems (that's the simplest way). The reason it happens is because compilers compiles every source (.cc) file separately from other files. On the other hand it needs to know what code exactly it needs to create (i.e. what is the T in template is substituted with), and it has no other way to know it unless the programmer tells it explicitly or includes all the code when template instantiation happens. I.e. when mylist.cc is compiled, it knows nothing about mylist users and what code needs to be created. On the other hand if listuser.cc is compiled, and all the mylist code is present, the compiler creates needed mylist code. You can read more about it in here or in Stroustrup.

Your code has problems, what if user requests negative or too large (more than amount of elements in the list). And i didn't look too much.

Besides, i don't know how u plan to use it, but your operator[] is O(N) time, which will probably easily lead to O(N*N) loops...

like image 9
Drakosha Avatar answered Nov 19 '22 11:11

Drakosha


Vectors have the erase method that can remove elements. Is that not sufficient?

like image 6
Sydius Avatar answered Nov 19 '22 10:11

Sydius