I have code like this:
#include <vector>
struct pollfd; // incomplete struct, since i did not included <poll>
struct Status{
// abstract representation of pollfd, epoll_event, kevent
int fd;
int status; // my own status representation
};
class iterator{
public:
hidden_pointer_iterator(const pollfd *pos) : pos(pos){}
bool operator !=(iterator const &other) const{
return ! ( *this == other);
}
bool operator ==(iterator const &other) const;
iterator &operator ++();
Status operator *() const;
private:
const pollfd *pos;
};
class PollSelector{
public:
// ...
iterator begin() const; // pull pointer to fds_.data()
iterator end() const; // pull pointer to fds_.data() + fds_.size()
private:
std::vector<pollfd> fds_;
};
I was able to make it run, by implementing all specific operations in the CPP file.
My question is - is there more "standard" way to do this iterator?
Update
My code compiles and works.
I am qurious if there are something in std that can do all this automatically, without so much coding.
A bit off-topic, IMO, this code abstracts away the wrong thing.
You should rather have multiple implementations of your demultiplexer engine interface, one that uses epoll, another for kevent, etc.. Demultiplexer engine interface is the one that allows you to register callbacks for file descriptor events, timers, signals, cross-thread, etc..
On Linux, there may be little point to using anything else but epoll.
Related
[Apologies if this question seems opinionated or discussionworthy.]
I have a class which, although not a collection class per se, does contain an arbitrary number of elements which are primarily constructed via an 'append' method:
append(TypeA thingA, TypeB thingB, TypeC thingC);
Significantly, there is not an auxiliary struct or class anywhere tying together a triple of (thingA, thingB, thingC), nor has one been needed so far -- the class works fine as-is.
Today I decided I needed an iterator for this class, that could return all the things I'd added to it, almost as if it were a collection, after all. The question is, what's the best way to return thingA, thingB, and thingC?
I could belatedly define an auxiliary tuple struct, just so that the iterator could return instances of it. But this seemed a little odd.
What I implemented instead was something along the lines of
class FunnyCollectionIter {
FunnyCollection* _ctx;
unsigned int _i;
public:
FunnyCollectionIter();
const TypeA& thingA() const;
const TypeB& thingB() const;
const TypeC& thingC() const;
FunnyCollectionIter& operator=(const FunnyCollectionIter &rhs);
FunnyCollectionIter& operator++();
bool operator==(const FunnyCollectionIter &rhs) const;
// ...
}
};
And I'm using it with code like this:
FunnyCollectionIter it;
for(it = funnycollection.begin(); it != funnycollection.end(); ++it) {
// now do things with it.thingA(), it.thingB(), and it.thingC()
}
But this seems a little odd, too. Normally (in the STL, at least) you access an iterator either using *, or ->first and ->second. But in the scheme I've implemented, there's no *, no ->, no first and second (let alone third?), and the interesting names thingA, thingB, and thingC are methods to invoke, not members to access.
So my question is, is this a poor way to construct an iterator in this situation, and is there a better way?
If it helps, the class is actually a scheduler. The three "things" in question are a duration, a callback, and an optional name. The caller constructs a schedule via one or more calls to append(), and then normally the schedule just runs, but now I have a need for the caller to be able to review the just-constructed schedule. (This is the same class I was referring to in this other question.)
You might split your class to have iterator interface on one side, and specific interface on the other side:
class FunnyWrapper
{
FunnyCollection* _ctx;
unsigned int _i;
public:
const TypeA& thingA() const;
const TypeB& thingB() const;
const TypeC& thingC() const;
// ...
// trick to use operator -> in iterator.
FunnyWrapper* operator ->() { return this; }
};
class FunnyCollectionIter
{
FunnyCollection* _ctx;
unsigned int _i;
public:
FunnyCollectionIter();
FunnyCollectionIter& operator=(const FunnyCollectionIter &rhs);
FunnyCollectionIter& operator++();
bool operator==(const FunnyCollectionIter &rhs) const;
// ...
FunnyWrapper operator->() { return FunnyWrapper{_ctx, _i}; }
FunnyWrapper operator*() { return FunnyWrapper{_ctx, _i}; }
};
I am designing an input iterator type that enumerates all running processes in a system.
This is similar to an iterator I designed to enumerate modules in a process. The module iterator takes a 'process' object in the constructor, and a default constructed iterator is considered to be the off-the-end iterator.
Example:
hadesmem::ModuleIterator beg(process);
hadesmem::ModuleIterator end;
assert(beg != end);
I do not know what to do about process enumeration though, because there is no 'state' or information that needs to be given to the iterator (everything is handled internally by the iterator using the Windows API).
Example:
// This is obviously a broken design, what is the best way to distinguish between the two?
hadesmem::ProcessIterator beg;
hadesmem::ProcessIterator end;
What is the idiomatic way to deal with this situation? i.e. Where you need to distinguish between the creation of a 'new' iterator and an off-the-end iterator when nothing needs to be given to the iterator constructor.
If it's relevant, I am able to use C++11 in this library, as long as it's supported by VC11, GCC 4.7, and ICC 12.1.
Thanks.
EDIT:
To clarify, I know that it's not possible to distinguish between the two in the form I've posted above, so what I'm asking is more of a 'design' question than anything else... Maybe I'm just overlooking something obvious though (wouldn't be the first time).
What you really want to do is create a kind of ProcessList object, and base the iterators on that. I wouldn't want to be enumerating all processes or something every time I increment an iterator.
If you create a class that holds the parameters that go into the CreateToolhelp32Snapshot() representing the snapshot you're iterating over, you'll have a natural factory for the iterators. Something like this should work (I'm not on Windows, so not tested):
class Process;
class Processes {
DWORD what, who;
public:
Processes(DWORD what, DWORD who) : what(what), who(who) {}
class const_iterator {
HANDLE snapshot;
LPPROCESSENTRY32 it;
explicit const_iterator(HANDLE snapshot, LPPROCESSENTRY32 it)
: snapshot(snapshot), it(it) {}
public:
const_iterator() : snapshot(0), it(0) {}
// the two basic functions, implement iterator requirements with these:
const_iterator &advance() {
assert(snapshot);
if ( it && !Process32Next(snapshot, &it))
it = 0;
return *this;
}
const Process dereference() const {
assert(snapshot); assert(it);
return Process(it);
}
bool equals(const const_iterator & other) const {
return handle == other.handle && it == other.it;
}
};
const_iterator begin() const {
const HANDLE snapshot = CreateToolhelp32Snapshot(what, who);
if (snapshot) {
LPPROCESSENTRY32 it;
if (Process32First(snapshot, &it))
return const_iterator(snapshot, it);
}
return end();
}
const_iterator end() const {
return const_iterator(snapshot, 0);
}
};
inline bool operator==(Processes::const_iterator lhs, Processes::const_iterator rhs) {
return lhs.equals(rhs);
}
inline bool operator!=(Processes::const_iterator lhs, Processes::const_iterator rhs) {
return !operator==(lhs, rhs);
}
Usage:
int main() {
const Processes processes( TH32CS_SNAPALL, 0 );
for ( const Process & p : processes )
// ...
return 0;
}
You could use the named constructor idiom.
class ProcessIterator
private:
ProcessIterator(int) //begin iterator
ProcessIterator(char) //end iterator
//no default constructor, to prevent mistakes
public:
friend ProcessIterator begin() {return ProcessIterator(0);}
friend ProcessIterator end() {return ProcessIterator('\0');}
}
int main() {
for(auto it=ProcessIterator::begin(); it!=ProcessIterator::end(); ++it)
//stuff
}
I'm wondering whether there is a good design pattern or idiom to realize the following:
You have an existing class that provides only a visitor interface, as follows
class Visitor {
public:
virtual ~Visitor() { }
virtual void visit(Node *n) = 0;
};
class Tree {
public:
void accept(Visitor *v);
};
And you want to have an interface that can be used as follows, which should iterate through the tree in the same order that the visitor would have its visit function called.
for(iterator it(...), ite(...); it != ite; ++it) {
/* process node */
}
The problem appears to be that when we just call visit, we are out of control, and can't temporarily "go back" to the loop body to execute the action for one node. This looks like it should occur regularly in real world programs. Any idea how to solve it?
In the general case, I don't think it's possible, at least not cleanly.
At least as it's usually defined, an iterator expects to deal with a homogeneous collection. I.e., an iterator is normally defined something like:
template <class Element>
class iterator // ...
...so a specific iterator can only work with elements of one specific type. The most you can do to work with differing types is create an iterator to (a pointer/reference to) a base class, and let it deal with objects of derived classes.
By contrast, it's pretty easy to write a visitor like this:
class MyVisitor {
public:
void VisitOneType(OneType const *element);
void VisitAnotherType(AnotherType const *element);
};
This can visit nodes of either OneType or AnotherType, even if the two are completely unrelated. Basically, you have one Visit member function in your Visitor class for every different type of class that it will be able to visit.
Looked at from a slightly different direction, an iterator is basically a specialized form of visitor that only works for one type of object. You exchange a little more control over the visitation pattern in exchange for losing the ability to visit unrelated types of objects.
If you only need to deal with one type (though that one type may be a base class, and the visited objects are of various derived types), then the obvious method would be to build a "bridge" class that visits objects (Tree nodes, in your example), and when its visit is called, it just copies the address of the node it's visiting into some collection that supports iterators:
template <class T>
class Bridge {
std::vector<T *> nodes;
public:
virtual void visit(T *n) {
nodes.push_back(n);
}
typedef std::vector<T *>::iterator iterator;
iterator begin() { return nodes.begin(); }
iterator end() { return nodes.end(); }
};
Using this would be a two-step process: first visit the nodes like a visitor normally would, then having collected together the nodes of interest you can iterate through them just like you would any other collection that provides iterators. At that point, your visitation pattern is limited only by the class of iterator provided by the collection you use in your bridge.
I had this problem in a real-world setting with an R-tree implementation that provided a visitor interface, whereas I needed an iterator interface. The suggestion by Jerry above works only if you can accept storing all the results in a collection. That may result in high memory consumption if your result set is huge and you don't really need to store them.
One solution that will work for sure is to launch the visitor in a separate thread and start waiting on a conditional variable for the results. When a visit call is made, you store the current result into a shared temp location, and use another conditional variable to wait for the next request. You signal the caller (main) thread's conditional variable before you wait on your own. The caller, which is implementing the iterator interface can then return the value stored at the temp location. During the next iteration, it could signal the visitor thread's conditional variable, and wait on its own for the next item. Unfortunately, this is somewhat costly if you do it on a per-item basis. You can buffer some items to improve the performance.
What we really need is an extra stack and to alternate between two contexts. This abstraction is provided by coroutines. In C++, boost::coroutine provides a clean implementation. Below I include a full example of how visitor pattern can be adapted into an iterator pattern.
#include <iostream>
#include <boost/bind.hpp>
#include <boost/coroutine/coroutine.hpp>
template<typename Data>
class Visitor
{
public:
virtual ~Visitor() { }
virtual bool visit(Data const & data) = 0;
};
template <typename Data>
class Visitable
{
public:
virtual ~Visitable() {}
virtual void performVisits(Visitor<Data> & visitor) = 0;
};
// Assume we cannot change the code that appears above
template<typename Data>
class VisitableIterator : public Visitor<Data>
{
private:
typedef boost::coroutines::coroutine<void()> coro_t;
public:
VisitableIterator(Visitable<Data> & visitable)
: valid_(true), visitable_(visitable)
{
coro_ = coro_t(boost::bind(&VisitableIterator::visitCoro, this, _1));
}
bool isValid() const
{
return valid_;
}
Data const & getData() const
{
return *data_;
}
void moveToNext()
{
if(valid_)
coro_();
}
private:
void visitCoro(coro_t::caller_type & ca)
{
ca_ = & ca;
visitable_.performVisits(*static_cast<Visitor<Data> *>(this));
valid_ = false;
}
bool visit(Data const & data)
{
data_ = &data;
(*ca_)();
return false;
}
private:
bool valid_;
Data const * data_;
coro_t coro_;
coro_t::caller_type * ca_;
Visitable<Data> & visitable_;
};
// Example use below
class Counter : public Visitable<int>
{
public:
Counter(int start, int end)
: start_(start), end_(end) {}
void performVisits(Visitor<int> & visitor)
{
bool terminated = false;
for (int current=start_; !terminated && current<=end_; ++current)
terminated = visitor.visit(current);
}
private:
int start_;
int end_;
};
class CounterVisitor : public Visitor<int>
{
public:
bool visit(int const & data)
{
std::cerr << data << std::endl;
return false; // not terminated
}
};
int main(void)
{
{ // using a visitor
Counter counter(1, 100);
CounterVisitor visitor;
counter.performVisits(visitor);
}
{ // using an iterator
Counter counter(1, 100);
VisitableIterator<int> iter(static_cast<Visitable<int>&>(counter));
for (; iter.isValid(); iter.moveToNext()) {
int data = iter.getData();
std::cerr << data << std::endl;
}
}
return EXIT_SUCCESS;
}
Building traversal logic in the visitors implementations is indeed not flexible. A usable way to cleanly separate traversing composite structures from visitation may be done via visitor combinators (there are other papers, feel free to google for them).
These slides about the same topic may also be of interest. They explain how to get clean syntax à la boost::spirit rules.
A set of APIs that I commonly use follow a linked-list pattern:
struct SomeObject
{
const char* some_value;
const char* some_other_value;
SomeObject* next;
}
LONG GetObjectList( SomeObject** list );
void FreeObjectList( SomeObject* list );
This API is not mine and I cannot change it.
So, I'd like to encapsulate their construction/destruction, access, and add iterator support. My plan is to do something like this:
/// encapsulate access to the SomeObject* type
class MyObject
{
public:
MyObject() : object_( NULL ) { };
MyObject( const SomeObject* object ) : object_( object ) { };
const char* SomeValue() const
{
return NULL != object_ ? object_->some_value : NULL;
};
const char* SomeValue() const
{
return NULL != object_ ? object_->some_other_value : NULL;
};
private:
SomeObject* object_;
}; // class MyObject
bool operator==( const MyObject& i, const MyObject& j )
{
return // some comparison algorithm.
};
/// provide iterator support to SomeObject*
class MyObjectIterator
: public boost::iterator_adaptor< MyObjectIterator,
MyObject*,
boost::use_default,
boost::forward_traversal_tag >
{
public:
// MyObjectIterator() constructors
private:
friend class boost::iterator_core_access;
// How do I cleanly give the iterator access to the underlying SomeObject*
// to access the `next` pointer without exposing that implementation detail
// in `MyObject`?
void increment() { ??? };
};
/// encapsulate the SomeObject* creation/destruction
class MyObjectList
{
public:
typedef MyObjectIterator const_iterator;
MyObjectList() : my_list_( MyObjectList::Create(), &::FreeObjectList )
{
};
const_iterator begin() const
{
// How do I convert a `SomeObject` pointer to a `MyObject` reference?
return MyObjectIterator( ??? );
};
const_iterator end() const
{
return MyObjectIterator();
};
private:
static SomeObject* Create()
{
SomeObject* list = NULL;
GetObjectList( &list );
return list;
};
boost::shared_ptr< void > my_list_;
}; // class MyObjectList
My two questions are:
How do I cleanly give MyObjectIterator access to the underlying SomeObject to access the next pointer in the linked list without exposing that implementation detail in MyObject?
In MyObjectList::begin(), how do I convert a SomeObject pointer to a MyObject reference?
Thanks,
PaulH
Edit: The linked-list APIs I'm wrapping are not mine. I cannot change them.
First, of course, for real use, you almost certainly shouldn't be writing your own linked list or iterator at all. Second, good uses for linked lists (even one that's already written, debugged, etc.) are also pretty rare -- except in a few rather unusual circumstances, you should probably use something else (most often vector).
That said, an iterator is typically a friend (or nested class) of the class to which it provides access. It provides the rest of the world with an abstract interface, but the iterator itself has direct knowledge of (and access to) the internals of the linked list (or whatever container) to which it provides access). Here's a general notion:
// warning: This is really pseudo code -- it hasn't been tested, and would
// undoubtedly require a complete rewrite to even compile, not to mention work.
template <class T>
class linked_list {
public:
class iterator;
private:
// A linked list is composed of nodes.
// Each node has a value and a pointer to the next node:
class node {
T value;
node *next;
friend class iterator;
friend class linked_list;
public:
node(T v, node *n=NULL) : value(v), next(n) {}
};
public:
// An iterator gives access to the linked list.
// Operations:
// increment: advance to next item in list
// dereference: access value at current position in list
// compare: see if one iterator equals another
class iterator {
node *pos;
public:
iterator(node *p=NULL) : pos(p) {}
iterator operator++() {
assert(pos);
pos = pos->next;
return *this;
}
T operator*() { return pos->value; }
bool operator!=(iterator other) { return pos != other.pos; }
};
iterator begin() { return iterator(head); }
iterator end() { return iterator(); }
void push_front(T value) {
node *temp = new node(value, head);
head = temp;
}
linked_list() : head(NULL) {}
private:
node *head;
};
To work along with the algorithms in the standard library, you have to define quite a bit more than this tried to (e.g., typedefs like value_type and reference_type). This is only intended to show the general structure.
My advice: Trash this and use an existing slist<> implementation. IIRC, it will be in C++1x, so your compiler(s) might already support it. Or it might be in boost. Or take it from someplace else.
Wherever you get it from, what you get has all these problems already solved, is likely very well tested, therefore bug-free and fast, and the code using it is easily recognizable (looking at it many of us would immediately see what it does, because it's been around for a while and it's going to to be part of the next standard).
The last time I wrote my own list class was before the STL became part of the C++ standard library.
Ok, since you're stuck with the API you have, here's something that might get you started:
class MyObjectList
{
public:
typedef SomeObject value_type;
// more typedefs
class iterator {
public:
typedef SomeObject value_type;
// more typedefs
iterator(SomeObject* pObj = NULL)
: pObj_(pObj) {}
iterator& operator++() {if(pObj_)pObj_ = pObj_->next;}
iterator operator++(int) {iterator tmp(*this);
operator++();
return tmp;}
bool operator==(const iterator& rhs) const
{return pObj_ == rhs.pObj_;}
bool operator!=(const iterator& rhs) const
{return !operator==(rhs);}
value_type& operator*() {return pObj_;}
private:
SomeObject* pObj_;
};
class const_iterator {
public:
typedef SomeObject value_type;
// more typedefs
const_iterator(const SomeObject* pObj = NULL)
: pObj_(pObj) {}
iterator& operator++() {if(pObj_)pObj_ = pObj_->next;}
iterator operator++(int) {iterator tmp(*this);
operator++();
return tmp;}
bool operator==(const iterator& rhs) const
{return pObj_ == rhs.pObj_;}
bool operator!=(const iterator& rhs) const
{return !operator==(rhs);}
const value_type& operator*() {return pObj_;}
private:
const SomeObject* pObj_;
};
MyObjectList() : list_() {GetObjectList(&list_;);}
~MyObjectList() {FreeObjectList(list_);}
iterator begin() {return list_ ? iterator(list_)
: iterator();}
const_iterator begin() const {return list_ ? const_iterator(list_)
: const_iterator();}
iterator end () {return iterator(getEnd_());}
const_iterator end () const {return const_iterator(getEnd_());}
private:
SomeObject* list_;
SomeObject* getEnd_()
{
SomeObject* end = list_;
if(list_)
while(end->next)
end = end->next;
return end;
}
};
Obviously, there's more to this (for example, I believe const and non-const iterators should be comparable, too), but that shouldn't be hard to add to this.
From what you said, you probably have a BIG legacy code using your struct SomeObject types but you want to play nicely with new code and use iterators/stl containers.
If that's the case, you will not be able to (in an easy way) use your new created iterator in all the legacy code base, since that will be changing a lot of code, but, you can write a templated iterator that, if your structs follow the same pattern, having a next field, will work.
Something like this (I haven't tested nor compiled it, it's just an idea):
Suppose you have your struct:
struct SomeObject
{
SomeObject* next;
}
You will be able to create something like this:
template <class T>
class MyIterator {
public:
//implement the iterator abusing the fact that T will have a `next` field, and it is accessible, since it's a struct
};
template <class T>
MyIterator<T> createIterator(T* object) {
MyIterator<T> it(object);
return it;
}
If you implement your iterator correctly, you will be able to use all the STL algorithms with your old structs.
PS.: If you're in a scenario of some legacy code with this kind of structs, I do too, and I implemented this workaround. It works great.
You would make MyObjectIterator a friend of MyObject. I don't see any better way. And really I think it's reasonable that iterators get whatever special friend access is necessary for them to perform their duties.
You don't seem to have considered how and where your MyObject instance are going to be stored. Or perhaps that's what this question is coming out of. It seems like you would have to have a separate linked list of MyObjects in your MyObjectList. Then at least MyObjectList::begin() can just grab the first MyObject of your internal linked list of them. And if the only operations that may modify or rearrange this list only ever happen through the iterators you provide, then you can problem keep these lists in synch without too much trouble. Otherwise, if there are functions in the API you're using that take the raw SomeObject linked list and manipulate it, then you may have trouble.
I can see why you've tried to design this scheme, but having separate MyObjects that point to SomeObjects even through SomeObjects themselves make up the real list structure.... That is not an easy way to wrap a list.
The simplest alternative is just to do away with MyObject completely. Let your iterators work against SomeObject instances directly and return those when dereferenced. Sure that does expose SomeObject to the outside, particularly its next member. But is that really a big enough problem to justify a more complex scheme to wrap it all up?
Another way to deal with might be to have MyObject privately inherit from SomeObject. Then each SomeObject instance can be downcast as a reference to a MyObject instance and given to the outside world that way, thus hiding the implemtation details of SomeObject and only exposing the desired public member functions. The standard probably doesn't guarantee this will work, but in practice since they'll likely have the exact same memory layouts you may be able to get away with it. However, I'm not sure that I would actually ever try such a thing in a real program unless absolutely necessary.
The last alternative I can think of is just to transfer the data into a list of more convenient data structures after being given to you by this API. And then of course transfer it back into a raw SomeObject list only if necessary to pass it back to the API. Just make your own SomeObjectData or whatever to store the strings and put them in a std::list. Whether or not this is actually feasible for you really depends on how this data is used in the context of the API you've mentioned. If there are other API functions that modify SomeObject lists and you need to use them frequently, then constantly converting SomeObject lists to and from std::list<SomeObjectData> could be annoying.
I've seen some very good answers so far but I fear they might be "bare".
Before blindingly charge in let's examine the requirements.
As you noticed the structure is similar to a singly linked list, the C++0x standard defines such a structure, called forward_list. Read up its interface, yours should come close.
The iterator type will be ForwardIterator.
I would like to expose one very annoying fact though: who's responsible for the memory ?
I am worried because there's no copy facility in the interface you've provided, so should we disable the copy constructor and assignment operator of our new list class ?
Implementation is easy, there's enough on this page even though the iterator don't properly implement the iterator traits in general, but I would consider ditching this idea completely and move on to a better scheme:
class MyObject { public: ... private: SomeObject mData; };
Wrapping up GetObjectList and returning a deque<MyObject>, I guess the LONG returns the number of items ?
I'd like to design a class Foo that stores various data of different types and returns iterators over them. It's supposed to be generic, so the user of Foo does not know how the data is stored (Foo could be using std::set or std::vector or whatever).
I'm tempted to write an interface like this:
class Foo {
class FooImpl;
FooImpl* impl_;
public:
const Iterator<std::string>& GetStrings() const;
const Iterator<int>& GetInts() const;
};
where Iterator is something like this (like iterators in .NET):
template<class T>
class Iterator {
public:
const T& Value() const = 0;
bool Done() const = 0;
void Next() = 0;
};
But I know that kind of iterator is not standard in C++, and it's better to use iterators the way the STL does, so you can use the STL algorithms on them.
How can I do that? (Do I need iterator_traits by any chance?)
Do you understand why the STL chose to put iterator implementation details in the header file? JIT frameworks are able to inline across compilation units, but C++ can only inline within a compilation unit. Advancing through a sequence is much faster when inlined, the cost of a function call dominates actually traversing the data structure.
If you really want to hide the implementation details, go ahead. You could make an STL-compatible iterator that implements operator++ and operator!= and operator-> in terms of protected virtual functions, the Next, Done, and Value you've mentioned would be decent names. Just expect to pay for the encapsulation with lower performance.
A c++ class with iterators has to provide at least two functions if they have to work with the std library
iterator begin() //returns an iterator at starting pos
iterator end() //returns an iterator one past end or just invald
The iterator has to overload the increment operators, equals and *
iterator operator++()
iterator operator==()//make sure that an invalid iterator equals end()
T& operator*()
You can use the iterator class to wrap around the iterator of the internal storage to ensure that the user is limited to these methods.
template <typename T> iter
{
iter(T::iterator& intern)
T::value_type& operator*(){return *intern}
iter operator++(){return iter(++intern);}
bool operator==(iter const& other)const{return intern == other.intern;}
}
Where T is the type of your container.(The class is incomplete and I may have mixed something up)
It almost looks like you're trying to create container-independent code, which is not (in general) a good idea, unless you are writing an algorithm which can operate solely with iterators. (See Scott Myers Effective STL Item 2: Beware the illusion of container-independent code)
The problem is that most of the standard containers do not provide overlapping functionality. If you're writing code for a particular container, assume you're writing code for that container. Don't bother trying to make it container-independent.
Use a typedef to return an boost::iterator_range. For example (never mind the names),
class Container
{
typedef std::vector<int> Collection;
public:
typedef boost::iterator_range<Collection::iterator> CollectionRange;
typedef Collection::iterator CollectionIterator;
Range range() const {
return make_iterator_range(collection_.begin(), collection_.end());
}
private:
Collection collection_;
};
The user code will be
Container c;
// ...
FOREACH(int i, c.range()) { //... }
Container::Range r = c.range();
for(Container::iterator j = r.begin(); j!= r.end(); j++) { // ... }
This is not generic, but the same idea can be used with templates.
To fulfill the requirement that the particular container (vector, set, ...) is not mentioned in the header file, and the user will be able to iterate over all strings, is to use the visitor pattern. The downside, of course, is that the user won't be able to use the STL algorithms on the strings.
// foo.h
class StringVisitor {
public:
void accept(const std::string& str) {
std::cout << str << std::endl;
}
};
class Foo {
class Impl;
Impl* impl_;
public:
Foo();
~Foo();
void VisitStrings(StringVisitor v) const;
};
// foo.cc
class Foo::Impl {
typedef std::vector<std::string> StringContainer;
StringContainer str_;
public:
Impl() {
str_.push_back("a");
str_.push_back("b");
}
void VisitStrings(StringVisitor v) const {
for(StringContainer::const_iterator it = str_.begin();
it != str_.end(); ++it){
v.accept(*it);
}
}
};
Foo::Foo() : impl_(new Impl()) {}
Foo::~Foo() {delete impl_;}
void Foo::VisitStrings(StringVisitor v) const {
impl_->VisitStrings(v);
}
// main.cc
int main() {
Foo foo;
foo.VisitStrings(StringVisitor());
return 0;
}