Extension std :: list

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

My code is as follows:

#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 when I try to use it, I get a linker error. Any ideas?

+6
c ++ list linker templates
Dec 14 '08 at 11:30
source share
8 answers

All template code should be placed in the header file. This is a binding issue with padding (which is the easiest way). The reason for this is because compilers compile each source file (.cc) separately from other files. On the other hand, he needs to know which code needs to be created (i.e., what replaces the T template in the template), and he has no other way to find out if the programmer does not explicitly say this or does not include all the code when the template an instance is created. That is, when mylist.cc is compiled, it knows nothing about my users and what code needs to be created. On the other hand, if listuser.cc is compiled and the entire mylist is present, the compiler generates the necessary mylist code. You can read about it here or at Stroustrup.

Your code has problems if the user requests negative or too large (more than the number of items in the list). And I did not look too much.

Also, I don't know how you plan to use it, but your [] operator is O (N) time, which is likely to easily lead to O (N * N) loops ...

+10
Dec 14 '08 at 11:34
source share

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

Container selection http://adrinael.net/containerchoice.png

+52
Dec 14 '08 at 16:44
source share

Given the original formulation of the problem,

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

there is no need to create your own list class (this is not a reasonable design choice, since std::list does not have a virtual destructor, which is convincing proof that it is not intended to be used as a base class).

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

 #include <vector> #include <algorithm> T value = ...; // whatever v.erase(std::remove(v.begin(), v.end(), value), v.end()); 
+21
Dec 14 '08 at 12:07
source share

Vectors have a delete method that can remove elements. This is not enough?

+6
Dec 14 '08 at 11:34
source share

In addition to other great comments, the best way to extend a standard container is not to output, but to create free functions. For example, see how Boost String Algorithms can be used to extend std::string and other std::string classes.

+5
Dec 14 '08 at 14:48
source share

You need to move all the template code to the header.

+1
Dec 14 '08 at 11:34
source share

The obvious material is already described in detail:

But the methods that you decide to implement?

  • Destructor
    • An unnecessary compiler will generate this for you.
  • Two different versions of the [] operator are pointless
    • Also you should be uisng std :: list :: size_type as an index
    • If you do not intend to support negative indexes.
  • There are no constant versions of the operator []
  • If you are going to implement [], you should also do in ()
  • You missed all sorts of ways to build a list.
  • Containers must define several types inside
+1
Dec 14 '08 at 12:34
source share

There is no need to call the std :: list destructor, because you are already exiting std :: list, when the destructor is called for myList, std :: list destructor will be called.

0
Dec 14 '08 at 15:03
source share



All Articles