GT 77
GT 77

Reputation: 458

Why does the ofstream << overload produce a different result when called as member function?

Below is the code:

#include <iostream>
int main()
{
    std::cout << 'a'; // a
    operator << (std::cout, 'a'); // a
    std::cout.operator << ('a'); // 97
}

Compiled with commands:

g++.exe -Wall -g -Wall -std=c++11  -c <cpp file> -o <o file>
g++.exe <exe file> <o file>  -O0 

Produces an output of aa97 when executed.

It seems that for some reason calling the operator << overload as a member function for std::cout invokes the template specialization for int, even if I passed a char. Is this right?

Why does it happen?

Upvotes: 1

Views: 73

Answers (3)

Ted Lyngmo
Ted Lyngmo

Reputation: 117812

It seems that for some reason calling the operator << overload as a member function for std::cout invokes the template specialization for int, even if I passed a char. Is this right?

Yes.

Why does it happen?

It's because there is no std::ostream::operator<<(char) overload so it'll be using std::ostream::operator<<(int) after the char 'a' has been converted to an int and 'a' has the ASCII value 97.

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

The class template std::basic_ostream has the following member operator

basic_ostream<charT, traits>& operator<<(int n);

but it does not have such a member for the type char.

For the type char there is a non-member template function

template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char);

So when you are using the member function then due to the integer promotions the argument of the type char is promoted to the type int

std::cout.operator << ('a');

But in this call

operator << (std::cout, 'a');

there is used the non-member template function

Upvotes: 2

Fran&#231;ois Andrieux
Fran&#231;ois Andrieux

Reputation: 29032

There is no operator<< member operator for std::basic_ostream which has a char argument. You can see the list of member operator<< here. The char overload is provided as a non-member operator operator<<(basic_ostream<T>&, char). You can see the list of non-member operator<< here.

When you use std::cout << 'a' both non-member and member operators are considered, of which the char overload is chosen. But when you use std::cout.operator<<('a') only member operators are considered. It has to resort to an int overload.

Upvotes: 6

Related Questions