25

Given this code, is it possible to change dumpStrings() to be able to iterate over any container of string, like say a list<string> ?

#include <vector>
#include <string>
#include <ostream>
#include <iostream>

using namespace std;

void dumpStrings(vector<string>::iterator it, vector<string>::iterator end)
{
    while (it != end) {
        cout << *it++ << endl;
    }
}

int main()
{
    vector<string> strVector;
    strVector.push_back("Hello");
    strVector.push_back("World");

    dumpStrings(strVector.begin(), strVector.end());
    return 0;
}
Simon P.
  • 522
  • 1
  • 4
  • 7
  • Why even limit it to strings? How about just `template dump(Iterator first, Iterator last);`? – GManNickG Feb 19 '11 at 23:10
  • This is just an example. I have something that consumes string and only string. I don't want to allow any other kind of item. – Simon P. Feb 20 '11 at 12:44

4 Answers4

29

Create a template

template<class iterator_type>
void dumpStrings(iterator_type it, iterator_type end)
{
    while (it != end) {
        cout << *(it++) << endl;
    }
}

The template also removes the limit of the container value type to string. Note that you need the parentheses around the it++.

flight
  • 7,162
  • 4
  • 24
  • 31
Fox32
  • 13,126
  • 9
  • 50
  • 71
  • 6
    While I think this is the best solution, it's not an answer to his question. (You should at least qualify your answer with "Why limit to strings?" or something, to make it clear you're going in a less-specific route.) – GManNickG Feb 19 '11 at 23:13
14

yes

http://www.boost.org/doc/libs/1_45_0/libs/utility/enable_if.html

http://www.cplusplus.com/reference/std/iterator/iterator_traits/

http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html

template<class I>
typename enable_if<
    is_same<typename iterator_traits<I>::value_type, string>
    >::type
function(...
KeatsPeeks
  • 19,126
  • 5
  • 52
  • 83
Anycorn
  • 50,217
  • 42
  • 167
  • 261
5

I don't think there's anything as simple as you'd like. Ideally, you could just do something like

void dumpStrings(AbstractIterator<string> beg, AbstractIterator<string> end) { }

but the STL iterators don't seem to have any inheritance hierarchy, irritatingly enough. So it looks like you're stuck with using function templates - that's how it's done in the STL Algorithms Library.

Sorry - I wish there was a better way, too, but this'll have to do. Just remember to declare the full function template in the header file!

Xavier Holt
  • 14,471
  • 4
  • 43
  • 56
-3

Please try this, this would work in all container:

template<class T>
void disp(T &t)
{
    for( auto itr=t.begin();itr!=t.end();itr++)
        cout<<*itr<<endl;
}

.cpp
    vector<int> v(3,77);
    list<string> l(5,"Hello");
    disp(l)
    disp(v);

Note: Don't forget to include<string>,
And auto is available in c++ 11

Raj
  • 263
  • 1
  • 2
  • 14