Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a function that takes an iterator or collection in a generic way?

I've been a Java programmer almost exclusively for the past 8 years or so, and recently I've been playing with C++ again. Here's an issue that I've come up against with regards to iterators in C++ STL and Java.

In Java, you can write a method that takes an iterator like this:

void someMethod(Iterator<String> data) {
    // ...
}

You pass in an Iterator and the method does not need to know what the underlying collection of that iterator is, which is good.

In C++, there is no common base class for iterators (as far as I know). I'd have to write a function like this:

void some_function(std::vector<std::string>::const_iterator data) {
    // ...
}

In other words, some_function knows that the iterator is an iterator over a vector. That's not good, because I want the function to work regardless of what the underlying collection of the iterator is.

How can I do this in C++? If it isn't really possible, then what is the best way to create a function in C++ that takes a collection as a parameter, but that doesn't need to know what the exact kind of collection is?

Addendum

Thanks for the answers. In addition to the answers I found some good information on this in paragraph 7.5 (Iterator Traits) of the book The C++ Standard Library: A Tutorial and Reference (by Nicolai M. Josuttis). Paragraph 7.5.1 explains how to write specialized versions of functions for different iterator categories.

like image 914
Jesper Avatar asked Sep 16 '25 22:09

Jesper


1 Answers

You probably want to consider a function template. Look at how some of std <algorithm> function templates work such as std::for_each.

e.g.

template< class Iterator >
void some_function( Iterator first, Iterator last )
{
    // ...
}

You can then call a function generated from this template with many kinds of iterable ranges.

e.g.

std::vector< double > my_doubles;
// ... populate doubles
some_function( my_doubles.begin(), my_doubles.end() );


std::set< Custom > my_custom_class_set;
// ... populate ...
some_function( my_custom_class_set.begin(), my_custom_class_set.end() );

int raw_array[50];
// ... populate ...
some_function( raw_array, raw_array + 50 );
like image 148
CB Bailey Avatar answered Sep 19 '25 12:09

CB Bailey