2

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?

Matthias
  • 9,817
  • 14
  • 66
  • 125
  • `std::ostream&` and [`while(std::getline(stream, line)) {...}`](http://en.cppreference.com/w/cpp/string/basic_string/getline). – BoBTFish Mar 24 '17 at 13:51
  • 1
    Question #1: Well, you are using it as an output stream, so, yes, it seems correct. Question #2 could be answered by an attempt to compile. – Algirdas Preidžius Mar 24 '17 at 13:53

3 Answers3

1

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.

Community
  • 1
  • 1
Jay
  • 636
  • 6
  • 19
1

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.

pergy
  • 5,285
  • 1
  • 22
  • 36
0

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.

CustodianSigma
  • 738
  • 9
  • 19