Jump to content
  • Advertisement
Sign in to follow this  
coordz

[C++] function to take both iterator and reverse_iterator

This topic is 3848 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've written a function to operate on a range like this
template <typename T> vector<T> myFunc(
    const typename vector< vector<T> >::const_iterator &beginIter,
    const typename vector< vector<T> >::const_iterator &endIter );
which works fine when passing normal forward iterators. When I try to pass reverse iterators I get an (expected) compile error. How do I define my function to take either forward or reverse iterators? Is there a base class that both forward and reverse iterators are derived from? Or do I need to further template my function to accept the two types of iterators? TIA

Share this post


Link to post
Share on other sites
Advertisement
You shouldn't care what kind of iterator you get, from a vector or not:

template <typename Iterator>
vector<typename Iterator::value_type> myFunc(Iterator begin, Iterator end)
{
// ...
}



This makes your function more general (the whole point of templates), because it can take user defined iterators. You could even template the return type, allowing greater flexibility.

Share this post


Link to post
Share on other sites
Quote:
Original post by coordz
I've written a function to operate on a range like this
template <typename T> vector<T> myFunc(
const typename vector< vector<T> >::const_iterator &beginIter,
const typename vector< vector<T> >::const_iterator &endIter );

rip-off has a good solution for you already, so I am going to go out on a limb and ask why you want to be returning a std::vector? Unless this is a factory function to initialise vectors, it might be better to operate in place, ala std::copy.

Share this post


Link to post
Share on other sites
I don't want to make the function any more generic than it is as it does not make sense for it to operate on anything other than a vector< vector<> >. To be brief, the function selects a path through a 2D grid of T and returns this path as a vector. I just want to be able to do a forward path and reverse path easily.

Share this post


Link to post
Share on other sites
You already have your answer:


template <typename T, typename Iter>
vector<T> myFunc(Iter beginIter, Iter endIter);

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
You shouldn't care what kind of iterator you get, from a vector or not:
*** Source Snippet Removed ***

This makes your function more general (the whole point of templates), because it can take user defined iterators. You could even template the return type, allowing greater flexibility.


Not all iterators provide the same level of functionality. What if myFunc uses some functionality of a random access iterator for instance which is not supported by a forward iterator? This contradicts your initial goal of making this function general.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ashkan
Not all iterators provide the same level of functionality. What if myFunc uses some functionality of a random access iterator for instance which is not supported by a forward iterator?

If you pass a forward iterator and your function expects a random access iterator, then you will get a compile time error immediately. Because it is a templated function, the compiler will discover immediately that the passed iterator has no random access functionality.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Quote:
Original post by Ashkan
Not all iterators provide the same level of functionality. What if myFunc uses some functionality of a random access iterator for instance which is not supported by a forward iterator?

If you pass a forward iterator and your function expects a random access iterator, then you will get a compile time error immediately. Because it is a templated function, the compiler will discover immediately that the passed iterator has no random access functionality.


Exactly my point. Then what's the point of making this function general? Why not pass a random access iterator in the first place?

Share this post


Link to post
Share on other sites
A lot of functions in the STL only support certain types of iterators, so while this function could be made more generic, it is not necessarily the right approach in all situations.

Reverse iterators have a base() method, which returns the corresponding iterator for the given range. That may be what you need to look into if you want to use the function as-is (though you may have to change the const_iterators to iterators).

Excellent article on this right here (specifically point 3 in your case)
Dr. Dobb's - Three Guidelines for Effective Iterator Usage

Share this post


Link to post
Share on other sites
Quote:
Original post by Ashkan
Not all iterators provide the same level of functionality. What if myFunc uses some functionality of a random access iterator for instance which is not supported by a forward iterator? This contradicts your initial goal of making this function general.


Since the OP didn't specify what the function was to do initially, I went for the most general one. People often over-specify template functions when there is a more general alternative available.

Besides, had the OP used a random access iterator specific construct (such as begin + 5) the compiler would reject an instantiation of the template for non random access iterator types, which is fine.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!