Search code examples
c++templatesiteratorvirtualmember-functions

Template Member Function to Write to Output Iterator


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.


Solution

  • 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.