下面是代码:
#include <iostream>
int main()
{
std::cout << 'a'; // a
operator << (std::cout, 'a'); // a
std::cout.operator << ('a'); // 97
}
用命令编译:
g++.exe -Wall -g -Wall -std=c++11 -c <cpp file> -o <o file>
g++.exe <exe file> <o file> -O0
执行时产生aa97
的输出。
似乎由于某种原因调用operator <<
重载作为std::cout
的成员函数调用int
的模板专门化,即使我传递了char
。这样对吗?
为什么会发生?
有char
实参的std::basic_ostream
没有operator<<
成员操作符。您可以在这里看到成员operator<<
的列表。char
重载作为非成员操作符operator<<(basic_ostream<T>&, char)
提供。你可以在这里看到非成员operator<<
的列表。
当您使用std::cout << 'a'
时,非成员和成员操作符都被考虑,其中char
重载被选择。但是当使用std::cout.operator<<('a')
时,只考虑成员操作符。它必须求助于int
重载。
类模板std::basic_ostream具有以下成员操作符
basic_ostream<charT, traits>& operator<<(int n);
,但是对于类型char
没有这样的成员。
对于char
类型,有一个非成员模板函数
template<class traits>
basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char);
当你使用成员函数时由于整型提升类型char
的参数被提升为int
std::cout.operator << ('a');
但是在这个调用中
operator << (std::cout, 'a');
使用了非成员模板函数
似乎由于某种原因调用
operator <<
重载作为std::cout
的成员函数调用int
的模板专门化,即使我传递了char
。这样对吗?
是的。
为什么会发生?
这是因为没有std::ostream::operator<<(char)
过载,所以在char
、'a'
被转换为int
和'a'
的ASCII值为97之后,它将使用std::ostream::operator<<(int)
。