Quote:
It's not possible to declare a friend from a template type from what I understand, so the iterator cannot directly make the base class a friend.
Actually, you can, and it is really just a syntax issue, but I think it is supposed to be fixed in the next standard. Every compiler I've used has some way around the issue. This should work for GCC and MSVC:
Code:
#if defined(__GNUC__)
#define TYPE_FRIENDLY(Type_t) friend class typify<Type_t>::type
#endif
#if defined(_MSC_VER)
#if (_MSC_VER >= 1300)
#define TYPE_FRIENDLY(Type_t) friend typename Type_t
#endif
#endif
Quote:
How would I go about making a customizable helper class? Or does it not need to be customized? The helper class would delegate the functions calls between the iterator and the base. Both the base and the iterator could make it friend, if it knew the actual name of this class (not passed as a template type, that is).
Use a template class for the coupler. You can declare an instance of a template class using a type passed as a parameter to a template class as a friend, no problem.
Quote:
So... anyway, suggestions, if you wouldn't mind, as to how to accomplish this.
I was thinking I could use it to enhance the relationship between an iterator and its base class. An iterator should be used to specify a range within the base class, and not a range within the data stored in the class. So if it resizes, and data is moved, the iterator would be invalidated. The base class notifies the iterator of this and allows the iterator to set a new position within the new memory region. Or it could simply tell the iterator that it is now invalidated, to catch mistakes.
Read up on the observer pattern--where the iterator would be registered implicitly as part of obtaining the iterator.
Quote:
Another would be that the iterator can ask the parent for the value at pos X, allow for greater customization of the iterator (it could work better, with more classes). And the best of all is that it could ask the parent to set data, as well. This is especially useful in a ranged iterator which emulates iterator behaviour (since there's not 1 element to change, there's several).
That's what all iterators do after a fashion--even this not range iterator, ranged iterator of yours. A vector based iterator need not do this, but an iterator for a table based container, for example, must do this. (The 'X' in most cases is "my position".)
Quote:
I was thinking of specializing std::backward_copy too. But I would need to specialize a version which uses my iterators, which again would leave the work with the iterators (the iterator would have to do the work!). So by better communication with the base class, it could avoid doing
*dst++ = *src++;
Would would be inefficient.
It would probably be faster if this iterator of yours did do most of the work--with an appropriate allocator/sharing the allocation object of the container object. If the iterator is used to overwrite existing data the container object need not be involved, but if the iterator is used to extend data, append/insert additional data, spawning an instance of a list and inserting all the new data in the target container object would be much better than calling the container object for each insertion--at least for vector based containers.
Soma