0

This has been puzzling me for a while: with printf, you provide formmatters to dictate how a parameter should be interpreted, but cout doesn't require this. How does cout know to read a variable according to the correct type?

  • It's C++. Nothing more, nothing less. `operator<<` is a function and it takes parameters. The parameters have types. That's how 'it' knows. End of mystery. – sehe Jun 30 '13 at 00:50

1 Answers1

2

It's called function overloading. In C++, you can have as many functions as you want with the same name (operator<< is the name in this case), as long as they take different parameter sets. cout doesn't dictate how the parameters are interpreted, the compiler does. Or rather, the compiler dictates which function is called, and that function dictates how the parameter is formatted. The compiler knows the type of each parameter, and calls the appropriate function accordingly.

For example, this calls ostream::operator<<(int)

cout << 10;

And this calls ostream::operator<<(double), which is a completely different function

cout << 3.14;
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • Shall we bother him with ADL? Say, why doesn't he need to do `using std::operator<<` before it works? – sehe Jun 30 '13 at 00:52
  • Ah, that makes sense. So if you had a custom class you wanted to be able to cout, you would simply overload << with a definition taking your class as a parameter? This is an entirely different question haha, but how does overloading work on a compiler level? – user2142343 Jun 30 '13 at 03:14
  • Oh, would gcc just use typeid and run through a switch statement of the types the function has been overloaded with? – user2142343 Jun 30 '13 at 03:26
  • @user2142343: How a compiler does what it does is a complex topic that requires a book, or several. I certainly can't cover it in a comment underneath an answer on stack overflow, even if I completely understood it myself. But I can tell you for sure that it doesn't use typeid. It doesn't need it. It keeps track of all objects, along with their types, in some kind of table. Usually a hash table. When it sees a function call, it looks up the types of the parameters in this table, then looks in another table (or another part of the same table) for functions matching that signature. – Benjamin Lindley Jun 30 '13 at 03:38
  • The compiler knows at compile time which types are involved in a function or operator invocation. There are lookup rules that are used to find the function to call. Therefore, the program doesn't have to use `typeid` to find out at runtime. Note that the compiler doesn't always know the "full" type: It could be that it only sees a `std::ostream` (static type) while this object actually refers to a `std::ofstream` (dynamic type) at runtime. This doesn't change the choice of overloads though, it only has an influence on virtual function calls. – Ulrich Eckhardt Jun 30 '13 at 14:00