Reputation: 603
I am making my own STL-like container - tree with any number of children
template<typename Type>
class Node
{
Type value;
Iterator AddChild(const Type & value);
void Remove(const Iterator & where);
...
};
I decided that iterator's operator*
should return value
of current node, but what should return operator->
? Currently, it returns Node<Type>*
and it very useful in such situations
Node<int>::Iterator it = tree.begin();
it->AddChild(4);
But my mentor said me, that operator->
should return Type*
. What is STL-like way to access Node's methods? Something like it.Ref().MyMethod()
doesn't look good.
Upvotes: 2
Views: 217
Reputation: 2518
Your mentor is right, the return type of operator->()
should be Type*
.
The big idea behind iterators is that they are just smart pointers to some locations inside the container. You can alter the value stored at that location (by assigning to *it
) or access its members, but to do more drastic (i.e. structural) changes to container contents, you have to have direct access to the container itself.
That's why in STL, there are no node's methods. Instead, there're container's methods (and also algorithms) that accept iterators as arguments.
In other words, the STL way of doing what you're trying to do is:
Node<int>::Iterator it = tree.begin();
tree.AddChild(it, 4);
Upvotes: 4
Reputation: 76236
The programmer expects it->method
to be equivalent to (*it).method
, so the operator->
should return pointer to the same thing that operator*
returns reference to. Normally that should be the value of the iterator, because that's the expected way to get at the value.
You can expose methods of the node as methods of the pointer, i.e. called as it.method
, but it's somewhat confusing and in most cases it would require extra data in the iterator compared to methods of the container taking iterator as argument. That's why STL always uses methods of the container taking iterator. E.g. container.insert(iterator, value)
inserts value
after iterator
.
Upvotes: 0
Reputation: 119847
operator->
should return YourTree::value_type*
and operator*
should return YourTree::value_type&
. (Actually a YourTree::pointer
and YourTree::reference
, but these are normally just aliases for *
and &
of the value type). Note the consistency. Without it, the standard algorithms will not work.
It is up to you to decide what the value_type is. It could well be Node
if you want. This however can be confusing and hard to implement consistently. I would leave it as Type
.
Upvotes: 1