J
jose luis fernandez diaz
Hi,
In "STL Containers & Iterators" chapter there is the example below:
#ifndef TOKENITERATOR_H
#define TOKENITERATOR_H
#include <string>
#include <iterator>
#include <algorithm>
#include <cctype>
struct Isalpha {
bool operator()(char c) {
using namespace std; //[[For a compiler bug]]
return isalpha(c);
}
};
class Delimiters {
std::string exclude;
public:
Delimiters() {}
Delimiters(const std::string& excl)
: exclude(excl) {}
bool operator()(char c) {
return exclude.find(c) == std::string::npos;
}
};
template <class InputIter, class Pred = Isalpha>
class TokenIterator: public std::iterator<
std::input_iterator_tag,std::string,ptrdiff_t>{
InputIter first;
InputIter last;
std::string word;
Pred predicate;
public:
TokenIterator(InputIter begin, InputIter end,
Pred pred = Pred())
: first(begin), last(end), predicate(pred) {
++*this;
}
TokenIterator() {} // End sentinel
// Prefix increment:
TokenIterator& operator++() {
word.resize(0);
first = std::find_if(first, last, predicate);
while (first != last && predicate(*first))
word += *first++;
return *this;
}
// Postfix increment
class Proxy {
std::string word;
public:
Proxy(const std::string& w) : word(w) {}
std::string operator*() { return word; }
};
Proxy operator++(int) {
Proxy d(word);
++*this;
return d;
}
// Produce the actual value:
std::string operator*() const { return word; }
std::string* operator->() const {
return &(operator*());
}
// Compare iterators:
bool operator==(const TokenIterator&) {
return word.size() == 0 && first == last;
}
bool operator!=(const TokenIterator& rv) {
return !(*this == rv);
}
};
#endif // TOKENITERATOR_H ///:~
When I run the program:
#include <set>
#include <iterator>
#include <streambuf>
#include <sstream>
using namespace std;
int main() {
ifstream in("/tmp/kk");
ostream_iterator<string> out(cout, "\n");
typedef istreambuf_iterator<char> IsbIt;
IsbIt begin(in), isbEnd;
Delimiters
delimiters(" \t\n~;()\"<>:{}[]+-=&*#.,/\\");
TokenIterator<IsbIt, Delimiters>
wordIter(begin, isbEnd, delimiters), it,
end;
it = wordIter++; // <<--
}
I get the next error:
Error: tok.cxx, line 24: no operator "=" matches these operands
operand types are: TokenIterator<std::istreambuf_iterator<char,
std::char_traits<char>>, Delimiters> =
TokenIterator<std::istreambuf_iterator<char,
std::char_traits<char>>, Delimiters>:roxy
it = wordIter++;
The problem is that the method:
Proxy operator++(int) {
Proxy d(word);
++*this;
return d;
}
don't return a TokenIterator object.
Any idea to fix this error ?
Thanks,
Jose Luis.
In "STL Containers & Iterators" chapter there is the example below:
#ifndef TOKENITERATOR_H
#define TOKENITERATOR_H
#include <string>
#include <iterator>
#include <algorithm>
#include <cctype>
struct Isalpha {
bool operator()(char c) {
using namespace std; //[[For a compiler bug]]
return isalpha(c);
}
};
class Delimiters {
std::string exclude;
public:
Delimiters() {}
Delimiters(const std::string& excl)
: exclude(excl) {}
bool operator()(char c) {
return exclude.find(c) == std::string::npos;
}
};
template <class InputIter, class Pred = Isalpha>
class TokenIterator: public std::iterator<
std::input_iterator_tag,std::string,ptrdiff_t>{
InputIter first;
InputIter last;
std::string word;
Pred predicate;
public:
TokenIterator(InputIter begin, InputIter end,
Pred pred = Pred())
: first(begin), last(end), predicate(pred) {
++*this;
}
TokenIterator() {} // End sentinel
// Prefix increment:
TokenIterator& operator++() {
word.resize(0);
first = std::find_if(first, last, predicate);
while (first != last && predicate(*first))
word += *first++;
return *this;
}
// Postfix increment
class Proxy {
std::string word;
public:
Proxy(const std::string& w) : word(w) {}
std::string operator*() { return word; }
};
Proxy operator++(int) {
Proxy d(word);
++*this;
return d;
}
// Produce the actual value:
std::string operator*() const { return word; }
std::string* operator->() const {
return &(operator*());
}
// Compare iterators:
bool operator==(const TokenIterator&) {
return word.size() == 0 && first == last;
}
bool operator!=(const TokenIterator& rv) {
return !(*this == rv);
}
};
#endif // TOKENITERATOR_H ///:~
When I run the program:
#include <set>
#include <iterator>
#include <streambuf>
#include <sstream>
using namespace std;
int main() {
ifstream in("/tmp/kk");
ostream_iterator<string> out(cout, "\n");
typedef istreambuf_iterator<char> IsbIt;
IsbIt begin(in), isbEnd;
Delimiters
delimiters(" \t\n~;()\"<>:{}[]+-=&*#.,/\\");
TokenIterator<IsbIt, Delimiters>
wordIter(begin, isbEnd, delimiters), it,
end;
it = wordIter++; // <<--
}
I get the next error:
Error: tok.cxx, line 24: no operator "=" matches these operands
operand types are: TokenIterator<std::istreambuf_iterator<char,
std::char_traits<char>>, Delimiters> =
TokenIterator<std::istreambuf_iterator<char,
std::char_traits<char>>, Delimiters>:roxy
it = wordIter++;
The problem is that the method:
Proxy operator++(int) {
Proxy d(word);
++*this;
return d;
}
don't return a TokenIterator object.
Any idea to fix this error ?
Thanks,
Jose Luis.