views:

96

answers:

3

Here is my issue:

I have a std::vector<AguiWidgetBase*> which is used to keep track of child controls.

I have these two functions to return iterators:

std::vector<AguiWidgetBase*>::const_iterator AguiWidgetBase::getChildBeginIterator() const
{
    return children.begin();
}

std::vector<AguiWidgetBase*>::const_iterator AguiWidgetBase::getChildEndIterator() const
{
    return children.end();
}

I then use it like this:

for(std::vector<AguiWidgetBase*>::const_iterator it = box->getChildBeginIterator(); 
    it != box->getChildEndIterator(); ++it)
{
    it->setText("Hello World");
}

and I get these errors:

Error   3   error C2039: 'setText' : is not a member of 'std::_Vector_const_iterator<_Ty,_Alloc>'   c:\users\josh\documents\visual studio 2008\projects\agui\alleg_5\main.cpp   112
Error   2   error C2839: invalid return type 'AguiWidgetBase *const *' for overloaded 'operator ->' c:\users\josh\documents\visual studio 2008\projects\agui\alleg_5\main.cpp   112

Why is it giving me these errors?

Thanks

+8  A: 

Because an iterator acts like a pointer, and in this case a pointer to a pointer.

You'd need:

(*it)->setText("Hello World"); // dereference iterator, dereference pointer
GMan
Is there a way I can change my iterators so that it-> works?
Milo
It's not the iterator. It's because the vector is a vector of pointers. Derefencing the iterator once gives you a pointer to an AguiWidgetBase, which you must dereference again to use.
Donnie
So there is no way to get it-> to work?
Milo
@Milo: Not easily, no. You could make your own iterator.
GMan
+1  A: 

Is there a way I can change my iterators so that it-> works?

Not directly, but you could do something like:

for(std::vector<AguiWidgetBase*>::const_iterator it = box->getChildBeginIterator(); 
    it != box->getChildEndIterator(); ++it)
{
    AguiWidgetBase* p = *it;

    p->setText("Hello World");
}
TheUndeadFish
A: 

As others have noted, this is because the objects stored in your vector are pointers, so you have an extra level of indirection to the actual objects.

You may be able to use a boost::ptr_vector to collect the AguiWidgets by pointer but work with them as though they're stored by value? I haven't used it extensively but my vague recollection is that it works that way.

Peter