If you want to wrap std::list and enrich it by some functionalities and, essentially, maintain some (or most) of the std::list interface (as the iteration capabilities) also in the wrapper, there are (at least) two possibilities.
One (composition) is to define begin(), end() methods and iterator type in the wrapper as to propagate them to the contained structure, as proposed by Andrea Araldo.
One (private inheritance) is to leverage private inheritance, which can be quite handy in some cases. Steps needed:
- privately derive from std::list
- implement the wrapper-specific methods, if any (what you need to add in the wrapper)
- expose in the wrapper interface the methods and types of the std::list public interface, which you are interested in, through the 'using-declaration' (http://en.cppreference.com/w/cpp/language/using_declaration).
For example, in the following there is a slight modification of the proposed snippet in this sense (WrapperPrivInh). In this case, also all the standard constructors of std::list are made available in the wrapper interface, for free.
Furthermore, for completeness, also WrapperCompos variation is proposed, where the list is contained into the wrapper, which exposes what is needed to support iterator-based loop. In this case, only the 'number of default elements' constructor is re-defined from scratch.
#include <list>
#include <iostream>
class MyClass
{
public:
MyClass() { std::cout<<"(DEBUG)MyClass::default constructor\n"; }
};
template<class T>
class WrapperPrivInh : private std::list<T>
{
public:
using std::list<T>::iterator; //for the iterator type
using std::list<T>::begin; // for the begin()
using std::list<T>::end; // and end() methods
using std::list<T>::list; // for the constructors, if needed
//std::list<T> elements;
//iterator begin(){ return elements.begin(); };
//iterator end(){ return elements.end(); };
};
template<class T>
class WrapperCompos
{
std::list<T> m_list;
public:
using iterator= typename std::list<T>::iterator; //for the iterator type
WrapperCompos(int const n) : m_list(n) { }
iterator begin(){ return m_list.begin(); };
iterator end(){ return m_list.end(); };
};
int main()
{
{
std::cout<<"Experiment with private inheritance"<<'\n';
WrapperPrivInh<MyClass> wrapper(3); // constructor witch builds N (3 here) MyClass default elements (derived "for free" from std::list)
for(WrapperPrivInh<MyClass>::iterator it = wrapper.begin(); it != wrapper.end(); ++it)
std::cout<<"Hi "<<&(*it)<<std::endl;
}
{
std::cout<<"\nExperiment with private inheritance"<<'\n';
WrapperCompos<MyClass> wrapper(3); // constructor witch builds N (3 here) MyClass default elements (derived "for free" from std::list)
for(WrapperCompos<MyClass>::iterator it = wrapper.begin(); it != wrapper.end(); ++it)
std::cout<<"Hi "<<&(*it)<<std::endl;
for( auto const& x : wrapper ) //range-for-loop syntax (from c++11)
std::cout<<"Hi2 "<<&x<<std::endl;
}
}
The private inheritance approach can be interesting to easily, and correctly, propagate the features of the wrapped structure to the wrapper. For instance the wrapper can be easily made compatible with std::algorithms if the wrapped structure is compatible with them, like std::list is.
Hope this helps.
Best