I thought I would be smart and create member functions that accepted output iterators. This way, I could avoid returning a collection or taking a collection by reference. For example:
template <typename TOutIterator>
void getHeaderNames(TOutIterator destination);
template <typename TOutIterator>
void getHeaderValues(std::string const& name, TOutIterator destination);
These functions will write their results to whatever iterator is passed in. This way, I don't have to worry whether I'm writing to a set, vector or ostream.
Now I don't feel so smart. I want to make these functions virtual so I can stub out the implementation in test. Unfortunately, template member functions can't be virtual, which makes sense.
Is there a way to keep these functions generic (write to anything) and allow them to be virtual at the same time? I want to avoid writing everything to a vector only to turn around and write it to standard out or whatever.
Let me know if I need to explain my situation more clearly.
You could use type erasure to manipulate polymorphic iterators, like the any_iterator
proposed by Thomas Becker (and later implemented in Boost.Range). You would end up with something along those lines:
typedef any_iterator<
std::string, // Value
Writable, // Access
Forward, // Traversal
> StringOutputIterator; // can represent any output iterator accepting strings
virtual void getHeaders(StringOutputIterator destination);
The idea of type erasure is to have a common base class for a set of otherwise unrelated types (which happen very often in C++, due to the use of templates). For instance, std::function
applies this idiom to callable objects, by allowing the manipulation of function pointers, functors or lambdas in a similar way.