自定义参数化流操纵符为何需要重载operator<<?
问题解答
核心原因:endl和你自定义的print_my_data属于完全不同的类型,匹配的operator<<重载规则不一样
std::endl本质是模板函数,它的原型近似为:
template <class CharT, class Traits> std::basic_ostream<CharT, Traits>& endl(std::basic_ostream<CharT, Traits>& os);
标准库已经预先为流重载了适配这类函数的operator<<,等效实现如下:
template< class CharT, class Traits > basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os, basic_ostream<CharT,Traits>& (*func)(basic_ostream<CharT,Traits>&) ) { return func(os); }
当你写cout << endl的时候,endl会退化为符合要求的函数指针,直接匹配到这个预定义的重载,不需要额外写代码就能调用。
- 你定义的
print_my_data是自定义类类型,C++标准库不可能预先为所有用户自定义类型提供operator<<重载,所以如果你不自己写对应operator<<的实现,编译器找不到能匹配ostream << print_my_data实例的重载,就会直接编译报错。
你额外写的这个operator<<,本质就是告诉编译器,遇到流对象 << print_my_data实例的调用时,要执行你定义的逻辑:调用print_my_data实例的operator()方法把内容输出到流里。
适配场景说明
如果是不需要传参的普通流操纵符,你可以直接把逻辑改成函数形式,不需要额外重载operator<<,使用体验和endl完全一致:
ostream& print_my_data(ostream& out) { return out << /* 你的输出逻辑 */ << endl; } // 调用方式 clog << print_my_data << endl;
但你现在实现的是带参数的参数化流操纵符,需要用类存储传入的参数,你现在的类+重载operator<<的写法就是C++的标准实现,重载operator<<是必要步骤,没有简化空间。
内容的提问来源于stack exchange,提问作者Zyama Krendel
相关产品推荐
相关产品推荐

