4

I want to have a function that outputs certain pieces of information to a specific designated source that is inputted to the function. In code, what I mean is:

function output( source ) {

source << "hello" << endl;

}

where source can be a ofstream or cout. So that I can call this function like so:

output(cout) or ofstream otp ("hello"); output(otp)

My question is, how do I characterize source to make this work? It's fair to assume that source will always be a member of the std class

Thanks!

Amit
  • 7,688
  • 17
  • 53
  • 68
  • 2
    Two asides: 1) `source` is on odd name for the place where data *goes to*. Doesn't data using *come from* a source? 2) Never say `endl` when you mean `'\n'`. See [`endl` fiasco](http://stackoverflow.com/questions/5492380/what-is-the-c-iostream-endl-fiasco/5492605#5492605). – Robᵩ Sep 27 '11 at 17:13
  • @Rob: you're right, `source` should probably changed. And thank you so much about the `endl` fiasco. I didn't know that at **all**!! especially when my program is going to do a lot of I/O!!! Perfect comment, +1 – Amit Sep 27 '11 at 17:41

5 Answers5

7
void output(std::ostream &source) {
    source << "hello" << std::endl;
}

or even:

template <T>
void output(T &source) {
    source << "hello" << std::endl;
}
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
4

Write your function as:

std::ostream& output(std::ostream& source )
{
  return source << "hello" << endl;
}

Then you can use it as:

output(cout);

//and 
ofstream otp ("hello"); 
output(otp);

//and
output(output(cout));
output(output(output(cout)));
output(output(output(output(cout))));

//and even this:
output(output(output(output(cout)))) << "weird syntax" << "yes it is" ;

By the way, if the output function has many lines, then you can write it as:

std::ostream& output(std::ostream& source )
{
  source << "hello" << endl;
  source << "world" << endl;
  //....
  return source;
}

The point is that it should return source. In the earlier version, the function returns source.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

You should pass an std::ostream& as argument

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
1
function output( source ) {
  source << "hello" << endl;
}

If this is a member function, the point of which is to dump data about objects of the class of which it is a member, consider renaming it to operator<<. So, instead of

class Room {
  ...
  // usage myRoom.output(otp)
  void output(std::ostream& stream) {
    stream << "[" << m_name << ", " << m_age << "]";
  }
};

rather, try this:

class Room {
  ...
  // usage opt << myRoom << "\n"
  friend std::ostream& operator<<(std::ostream& stream, const Room& room) {
    return stream << "[" << room.m_name << ", " << room.m_age << "]";
  }
};

That way, you can display the state of your class using a more natural syntax:

std::cout << "My Room: " << myRoom << "\n";

instead of the klunky

std::cout << "My Room: ";
myRoom.output(std::cout);
std::cout << "\n";
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

IMHO, redirecting output should be done at the user level. Write your C++ like this:

cout << "hello" << endl;

And when executing the application, user can redirect the output to whatever he wants, say a file:

myapp > myfile
m0skit0
  • 25,268
  • 11
  • 79
  • 127
  • You're certainly right, and I do plan to do that. But my application outputs a lot of information that is somewhat irrelevant for the calculations I'll need this specific file for. So I like to choose sources. – Amit Sep 27 '11 at 15:49
  • You can always filter the file, or just redirect only what you want, or use different output streams for each one. Just in case you didn't know, you can still redirect any output stream like this myapp 2> myfile, myapp 3> myfile and so on. – m0skit0 Sep 27 '11 at 15:56