This post reminded me of another option. Prog-bman posted the prototype for the find_if template function:
Code:
template<class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last, Predicate pred);
Now, we can see that if we supply different types for first and last, the compiler will be unable to deduce which type to use for InputIterator, and give the ambiguous warning. However, rather than letting the compiler deduce a type for InputIterator, we can explicitly provide it:
Code:
// i is a string::const_iterator and str.end() is a string::iterator so type can not be deduced...
i = find_if<string::const_iterator>(i, str.end(), not_space);
One could also use a cast.
Code:
string::const_iterator j = 0;
This line will not compile in Dev-C++/G++:
Code:
conversion
from `int' to non-scalar type `__gnu_cxx::__normal_iterator<const char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
requested
Finally, here is a version of the code that removes the need for the space and not_space functions:
Code:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm> // for find_if
#include <iterator> // for ostream_iterator
#include <functional> // for not1
#include <cctype> // for isspace
using namespace std;
int main()
{
string str = "Ah, a nice short string.";
vector<string> words; // container for the individual words
string::iterator i = str.begin();
string::iterator j;
while(i != str.end())
{
i = find_if(i, str.end(), // looks for the first character in the string,
not1(ptr_fun((int (*)(int)) isspace))); // starting at i and occuring before end
j = find_if(i, str.end(), // looks for the first space after i, which
(int (*)(int)) isspace); // is the end of the word
words.push_back(string(i,j)); // uses the string constructor with two
// iterators denoting a range of characters
i = j; // move i to the end of the word
}
// display the words:
for(size_t x = 0; x < words.size(); x++)
{
cout << words[x] << endl;
}
// ...or the iterator way:
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n") );
}