Small improved std::list to manage doubloons and pointers I am extending std::list in order to have access to convenience member functions that simplify my everyday developments (e.g. ways to deal with doubloons, delete all the stored pointers, etc.). I removed some of these member functions, but I kept the essential ones.

#ifndef __PJ_LIST_H__
#define __PJ_LIST_H__

#include &lt;list&gt;
#include &lt;iostream&gt;

// This class is a wrapper of std::list to provide some smarter functionalities
template&lt;class T&gt;
class PjList: public std::list&lt;T&gt;
{
    public:

        typedef typename PjList&lt;T&gt;::iterator PjIterator;

        PjList() {};
        virtual ~PjList() {};

        // Helper functions to deal with doubloons
        bool contains(const T&amp; t);
        bool containsDoubloons();
        PjList&lt;T&gt; removeDoubloons();

        // Calls destructor of all list item and empty the list
        void destroyContents();

        // Accessing elements at index
        T&amp; at(int index);

        // Inserting element around "ref"
        bool insertItem(const T&amp; item, const T&amp; ref, bool before = true);

};

template&lt;class T&gt;
bool PjList&lt;T&gt;::contains(const T&amp; t)
{
    PjIterator it;

    for( it = std::list&lt;T&gt;::begin(); it != std::list&lt;T&gt;::end(); it++ )
    {
        if ( *it == t )
            return true;
    }
    return false;
}

template&lt;class T&gt;
bool PjList&lt;T&gt;::containsDoubloons()
{
    PjIterator it;
    PjIterator jt;
    int nb_occurence;

    for( it = std::list&lt;T&gt;::begin(); it != std::list&lt;T&gt;::end(); it++ )
    {
        nb_occurence = 0;
        for( jt = std::list&lt;T&gt;::begin(); jt != std::list&lt;T&gt;::end(); jt++ )
        {
            if ( *it == *jt )
                nb_occurence += 1;
        }
        if ( nb_occurence &gt; 1 )
            return true;
    }
    return false;
}

template&lt;class T&gt;
PjList&lt;T&gt; PjList&lt;T&gt;::removeDoubloons()
{
    PjList&lt;T&gt; output;

    PjIterator it;
    for( it = std::list&lt;T&gt;::begin(); it != std::list&lt;T&gt;::end(); it++ )
    {
        T&amp; t = *it;
        if ( !output.contains(t) )
            output.push_back(t);
    }

    return output;
}

template&lt;class T&gt;
void PjList&lt;T&gt;::destroyContents()
{
    PjIterator it;

    for( it = std::list&lt;T&gt;::begin(); it != std::list&lt;T&gt;::end(); it++ )
        delete *it;

    std::list&lt;T&gt;::clear();
}

template&lt;class T&gt;
bool PjList&lt;T&gt;::insertItem(const T&amp; t, const T&amp; ref, bool before)
{
    bool ref_found = false;

    PjIterator it;

    for( it = std::list&lt;T&gt;::begin(); it != std::list&lt;T&gt;::end(); it++ )
    {
        if ( *it == ref )
        {
            ref_found = true;
            break;
        }
    }

    if ( !ref_found )
    {
        std::cerr &lt;&lt; "Insertion in list failed since ref item is not found" &lt;&lt; std::endl ;
        return false;
    }

    insert(it, t);
    return true;
}

template&lt;class T&gt;
T&amp; PjList&lt;T&gt;::at(int index)
{
    static T dummy;
    int i = 0;
    PjIterator it;

    for( it = std::list&lt;T&gt;::begin(); it != std::list&lt;T&gt;::end(); it++ )
    {
        if ( index == i++ )
            return *it;
    }
    std::cerr &lt;&lt; "Bad index " &lt;&lt; index &lt;&lt; std::endl ;
    return dummy;
}

#endif
I see no reason to have this be an entirely new data structure that inherits from std::list&lt;T&gt;. All of the new member functions you've defined are really just wrapper functions that could just be delegated to std::list&lt;T&gt; functions or functions that could be implemented as regular procedural functions.

For example, the contains() and at() and insertItem() (which should really just be named insertItemBefore()) functions could simply be:

namespace list_util {

template &lt;class T&gt;
bool contains(const std::list&lt;T&gt;&amp; l, const T&amp; elem)
{
    return std::find(l.begin(), l.end(), elem) != l.end();
}

template &lt;class T&gt;
T&amp; at(const std::list&lt;T&gt;&amp; l, std::size_t index)
{
    assert(index &lt; l.size());
    auto begin = l.begin();
    std::advance(begin, index);
    return *begin;
}

template &lt;class T&gt;
bool insertItemBefore(std::list&lt;T&gt;&amp; l, const T&amp; ref_item, const T&amp; elem)
{
    auto itemItr = std::find(l.begin(), l.end(), ref_item);

    // if we found the item, itemItr != l.end()
    if (itemItr != l.end()) {
        l.insert(itemItr, elem);
        return true;
    }
    return false;
}

}


You'd have to #include&lt;algorithm&gt; and #include&lt;iterator&gt; for this to work. Notice that the index parameter is now std::size_t to avoid having to check for negative indexes. They could then simply be called as: list_util::contains(the_list, elem); and list_util::at(the_list, the_index);.

Moreover, containsDoubloons() could be implemented using std::find() and destroyContents() is really just a call to std::list&lt;T&gt;::clear():

namespace list_util {

template&lt;class T&gt;
bool containsDoubloons(const std::list&lt;T&gt;&amp; l)
{
    for (auto it = l.begin(); it != l.end(); ++it) {
        const auto beginItr = std::next(it);
        if (beginItr != l.end() &amp;&amp; 
            std::find(beginItr, l.end(), *it) != l.end()) {
            return true;
        }
    }
    return false;
}

template&lt;class T&gt;
void destroyContents(std::list&lt;T&gt;&amp; l)
{
    l.clear();
}

}


Moreover, since the new functions we've written are completely generic and use the STL iterators for all operations, there's no reason to limit them only to std::list&lt;T&gt;. We could allow any container of containing T to be a parameter. An example is the contains() function:

template &lt; template &lt;class&gt; class C, class T&gt;
bool contains(const C&lt;T&gt;&amp; cont, const T&amp; elem)
{
    return std::find(cont.begin(), cont.end(), elem) != cont.end();
}