I have a class which contains a vector V (which is a private variable). The class has a member function which searches V for certain elements E and needs to return those elements. I don't want the caller to be able to change the elements of the vector (at least through the returned elements).
As I see it the options are as follows:
1. Return a vector of the matching Es
2. Return a vector of const_iterators to the matching Es
I think 2 is better because it allows for more easier access to V - e.g. if I wanted to have a separate function which deletes all of the matching Es , I could simply pass the vector of const-iterators.
I was just wondering whether (2) is good practice - is there anything which I should be aware of?
It's a clear win to simply return a container of E where possible, but it may not be sufficient. A container of copies eliminates concerns about lifetime and pointer/iterator invalidation, and hides implementation details. It also requires taking many copies and perhaps extra space.
If iterators are exposed, the API need to ensure that it does not step on the user's toes by invalidating those iterators/pointers/refwrappers too early, and the user needs to ensure that he or she maintains the API's invariants (by, e.g., not removing elements the API depends on). In general, this requires imposing requirements on the user, as well as exposing certain traits of the backing container, including iterator invalidation behavior, for example, and the iterator model.
One would prefer to keep this information internal to the class or subsystem which manages that vector, rather than allowing the user to muck about with it - it's much simpler that way.
Don't return iterators. The caller shouldn't know or care about how you store the data. Also iterators can be incremented and decremented. Do you really want your caller to be able to walk around your collection?
Return a vector of std::reference_wrappers as Eniozat suggested or a vector of pointers.
Be 100% clear in your documentation about how long the underlying data remains valid. If there is any question then bite the bullet and return a vector of E's.