Having toyed with this I suspect it isn't remotely possible, but I thought I'd ask the experts. I have the following C++ code:
class IInterface
{
virtual void SomeMethod() = 0;
};
class Object
{
IInterface* GetInterface() { ... }
};
class Container
{
private:
struct Item
{
Object* pObject;
[... other members ...]
};
std::list<Item> m_items;
};
I want to add these methods to Container:
MagicIterator<IInterface*> Begin();
MagicIterator<IInterface*> End();
In order that callers can write:
Container c = [...]
for (MagicIterator<IInterface*> i = c.Begin(); i != c.End(); i++)
{
IInterface* pItf = *i;
[...]
}
So essentially I want to provide a class which appears to be iterating over some collection (which the caller of Begin() and End() is not allowed to see) of IInterface pointers, but which is actually iterating over a collection of pointers to other objects (private to the Container class) which can be converted into IInterface pointers.
A few key points:
MagicIterator
is to be defined outside Container
.
Container::Item
must remain private.
MagicIterator
has to iterate over IInterface
pointers, despite the fact that Container
holds a std::list<Container::Item>
. Container::Item
contains an Object*
, and Object
can be used to fetch IInterface*
.
MagicIterator
has to be reusable with several classes which resemble Container, but might internally have different list implementations holding different objects (std::vector<SomeOtherItem>
, mylist<YetAnotherItem>
) and with IInterface*
obtained in a different manner each time.
MagicIterator
should not contain container-specific code, though it may delegate to classes which do, provided such delegation is not hard coded to to particular containers inside MagicIterator
(so is somehow resolved automatically by the compiler, for example).
- The solution must compile under Visual C++ without use of other libraries (such as boost) which would require a license agreement from their authors.
- Also, iteration may not allocate any heap memory (so no
new()
or malloc()
at any stage), and no memcpy()
.
Thanks for your time, even if you're just reading; this one's really been bugging me!
Update: Whilst I've had some very interesting answers, none have met all the above requirements yet. Notably the tricky areas are i) decoupling MagicIterator from Container somehow (default template arguments don't cut it), and ii) avoiding heap allocation; but I'm really after a solution which covers all of the above bullets.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…