Search code examples
c++operator-overloadingostream

Oveloading the ostream << operator for a sequence


I would like to define the operator << to operate on a sequence of elements, in a way like the STL algorithms work, by taking as arguments the first and last element of a container. As opposed to taking only one argument, the container itself, e.g.

std::ostream& operator<< ( std::ostream &out, std::list inList );

So that I would only have to write one function that would work regardless of if I am using list, vector, array, etc. And I would have to call the function with two arguments, inList.begin() and inList.end()

The problem is that operator<< takes only one argument. What is the best way to overcome this?

EDIT: Thank you for your answers. I should probably have made it more clear that I would prefer to have the ability to print a range of elements, including possibly a subsequence of a container (again, like STL algorithms). E.g. if a vector v has 5 elements, I wish could print them all giving a sequence from v.begin() to v.end() with an output like this:

[element1 element2 element3 element4 element5]

But I wish I also could print the first three only, in the range [v.begin(), v.begin()+3)

[element1 element2 element3]

Would your suggested answers work in this case?


Solution

  • You cannot get away from passing one argument, but you want something to work with any kind of container. So ideally you would want a function like

    template <typename T>
    std::ostream& someFunction(std::ostream& out, T first, T last) {
      // do your stuff
    }
    

    and an ostream& operator<< looking something like

    template <T>
    std::ostream& << (std::ostream& out, const T& sequence) {
      return someFunction(out, sequence.begin(), sequence.end());
    }
    

    However, this operator will clash with predefined ones, so you cannot just implement it like that. Fortunately you can play some template magic to get around this, and to see a very nice solution, check out this SO question and the corresponding github project

    Note that since (presumably) the objective is to have a generic ostream& operator<< for containers, and you would achieve this via a function template, it is not essential to have the function take iterators. It could also work taking a (const) reference to the container.