Matthias
Matthias

Reputation: 10379

Printing either to console or to a string/stream

I need a C++ function that dumps some text data (multiple lines) to the console:

void DumpData() const
{
    std::cout << "My Data 1" << std::endl;
    std::cout << "My Data 2" << std::endl;
}

This should be the default behaviour, however, it must also be possible to pass some other stream object that would be used instead of std::cout, something like this:

void DumpData(std::ostream& Stream = std::cout) const
{
    Stream << "My Data 1" << std::endl;
    Stream << "My Data 2" << std::endl;
}

Now to my questions:

  1. What is the correct type I should use for the paramter (std::ostream& in this example)?
  2. What is the default value, can I use = std::cout directly?

Moreover (3.), after the call to this function, if I pass my own stream object, I need to iterate over all strings in this stream line by line. What would be the best way to achieve this?

Upvotes: 2

Views: 2318

Answers (3)

CustodianSigma
CustodianSigma

Reputation: 746

Adding to @Jay 's answer, you could use a template parameter to be able to use a variety of streams such as std::stringstream or a std::iostream as long as the template parameter supports the << operator.

template <typename T> // = decltype(something)
void DumpData(T& Stream = std::cout) const
{
    Stream << "My Data 1" << std::endl;
    Stream << "My Data 2" << std::endl;
}

You can take it one step further by ensuring the type T provided overloads the operator <<.

Also in some cases, certain (possibly custom) streams may not be able to support std::endl so it might be safer to default to using \n which is always nicer since it avoid unnecessary flushes.

Upvotes: 0

pergy
pergy

Reputation: 5531

Why don't you just try it yourself?

Here's you code in Coliru for std::cout and std::stringstream as an example (constness of DumpData removed obviously):

#include <iostream>
#include <sstream>

void DumpData(std::ostream& Stream = std::cout)
{
    Stream << "My Data 1" << std::endl;
    Stream << "My Data 2" << std::endl;
}
int main() {
    DumpData();
    std::stringstream ss;
    DumpData(ss);
    std::string l;
    while(std::getline(ss, l)) {
        std::cout << l << std::endl;
    }
    return 0;
}

Output is what you expected.

Upvotes: 1

Jay
Jay

Reputation: 656

1 and 2 are correct. Your other option is to use std::ostringstream, but since std::cout is a std::ostream you would need to define another function with this signature.

To iterate the custom output, I would convert the stream to a string, then use some kind of string splitting to read each line.

Upvotes: 1

Related Questions