为什么当调用为成员函数时,流<<重载会产生不同的结果?



下面是代码:

#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)

相关内容

  • 没有找到相关文章

最新更新