Given a functor appropriate for use with std::for_each
and friends:
template <typename T> struct Foo {
void operator()(T const& t) { ... }
};
std::for_each(v.begin(), v.end(), Foo<Bar>());
Is there some standard way to convert this into an output iterator appropriate for use with std::copy
and friends? (or the opposite adaptation) Something like:
std::copy(v.begin(), v.end(), functor_output_iterator(Foo<Bar>()));
Which would call the functor each time a value is assigned to the iterator:
adapter(F f) : functor(f) { }
adapter& operator*() { return *this; }
operator=(T const& t) { functor(t); }
operator++() { }
...
Or, alternatively:
std::for_each(..., some_adapter(std::ostream_iterator(std::cout)));
Background:
I have a class that exposes a collection using an output iterator:
template <typename It> GetItems(It out) {
MutexGuard guard(mutex);
std::copy(items.begin(), items.end(), out);
}
This allows callers to get access to the items without forcing them to use a specific container type and without messing around with locking or other internal details.
e.g., to get only unique items:
std::set<whatever> set;
obj->GetItems(std::inserter(set, set.end()));
This beats the hell out of:
ObjLock lock = obj->GetLock();
for (int i = 0; i < obj->GetItemCount(); ++i) {
Item* item = obj->GetItem(i);
...
Now I also want to be able to aggregate these items, rather than copying them. (See this question). Where I would normally do something like:
std::for_each(v.begin(), v.end(), Joiner<Foo>());
Now I could make two separate methods for the same data elements, one that calls std::copy
and one that calls std::for_each
but it would be nice to be able to define just one such method, using an iterator or a functor, and have callers be able to pass either functors or iterators to it, adapting them as necessary to the appropriate type.
What I'm doing now is defining the aggregator in such a way that it can be used as either an output iterator or a functor, but this leads to unwanted complexity.
How about boost::function_output_iterator?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With