Without actuation, the compiler first searches for a suitable member function from std::ostream , and it finds one for int . Therefore, it implicitly converts your 1-byte number of type anyoldname to int and calls a member function.
Compiling your program with g ++ 4.8.1, two definitions for ostream::operator<< are shown:
U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@@GLIBCXX_3.4 U std::ostream::operator<<(int)@@GLIBCXX_3.4
The first for endl , and the second for your listing.
With an explicit cast to char, the compiler can find a perfect match in the global function std::operator<< , which takes ostream and char as input. Then it uses this function, and does not perform implicit casting (before int again) to call the ostream member ostream .
Two characters:
U std::ostream::operator<<(std::ostream& (*)(std::ostream&))@@GLIBCXX_3.4 U std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)
and your values ββare printed as characters, not their decimal values.
source share