Reputation: 1095
So, I'm designing a class which connects (over network) to a service to receive some data. I don't know how man data points I will be receiving in advance. Nevertheless I was wondering, if there is a way to make this class iterable using a forward_iterator in order to enjoy the STL in its full glory. My idea was something like:
self_type operator++() {
// if there are some locally cached data points left return next
// else connect to service again to receive the next batch of data
}
However, as I cannot provide a valid end()
, I'm curious, if this is somehow still possible to do.
An alternative (and iterator-less) interface would probably look something like:
bool hasMoreDataPoints() const;
DataPoint& getNext();
which obviously won't work with any STL-algorithm.
Upvotes: 0
Views: 436
Reputation: 15468
I suppose there is some type of storage which you use in your class for caching, e.g. a std::vector
. You can then just expose its std::begin()
and std::end()
iterators (in all the usual forms). Algorithms then directly work on the underlying container, and use the container-iterator's member functions like operator++
, operator==
and so on.
In case you need to introduce more logic, you need to create your custom iterator. Such can be basically done by composition, i.e. write a new class which contains an iterator corresponding to your storage container, and expose all functionality you need while adjusting it accordingly.
EDIT: as you said you use a list:
struct DataPoints
{
std::list<double> _list;
auto begin() const
{
return _list.begin();
}
auto end() const
{
return _list.end();
}
//other versions: non-const begin and end, cbegin, cend
}
That's it already for the simple approach. You can use that just as a normal list:
DataPoints d;
std::find(d.begin(), d.end(), 10.0);
As said, if you need more logic, you probably need to write a custom iterator.
Upvotes: 0
Reputation: 1940
However, as I cannot provide a valid end(), I'm curious, if this is somehow still possible....
You could use any of the container classes that comes with STL. Assume you are using a vector or a list or any other suitable container. Just use what's provided by STL and write your own wrapper
vector<datapoint> mydpvector;
//as data comes in
mydpvector.push_back(newdp);
vector<datapoint>::const_iterator cit=mydpvector.begin();
//now iterate everytime over the container
for(cit;cit!=mydpvector.end();cit++)
{
//get the data you need
}
//alternately if you need just the last element do this
mostrecentdp = mydpvector.back();
Upvotes: 0
Reputation: 302767
Do as the standard library do with istream_iterator
: when you run out of data, set your iterator state such that it compares equal to a default-constructed object of that type. And then there's your end()
equivalent.
Upvotes: 4