c++ - 参数化自定义流操纵器 - 为什么重载“operator<<”?
问题描述
我正在尝试为一组数据实现参数化流操纵器。我按照推荐的简单方法进行操作:
class print_my_data
{
private:
. . .
public:
print_my_data(. . .) { . . . }
ostream& operator()(std::ostream& out)
{
return out << . . . << endl;
}
};
ostream& operator<<(ostream& out, print_my_data md) // <=== MY QUESTION BELOW IS ABOUT THIS
{
return md(out);
}
用法:
clog << print_my_data(. . .) << endl;
这很好用;但我真的不明白为什么它不起作用,除非我定义operator<<
!为什么它不调用与它相同的重载函数endl
?(即作为可以通过 应用于流的对象operator()
)
解决方案
您要查找的重载仅为函数指针定义。
basic_ostream& operator<<( std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
您的print_my_data
类是一个可调用对象(一个仿函数,在 C++ 术语中)。但它不是函数指针。另一方面,是一个函数,因此有一个函数指针(事实上,它是 C++ 标准库中endl
为数不多的有地址的函数之一)
可以提出一个不合理的论点,即重载应该看起来像
basic_ostream& operator<<( std::function<std::basic_ostream<CharT,Traits>&(std::basic_ostream<CharT,Traits>&)> func);
但是,std::function
在编写 I/O 操作运算符时,它还不存在。就此而言,概念也不是。并使用 SFINAE 声明
template <typename F> basic_ostream& operator<<( F func);
会打开一整个潘多拉魔盒,里面满是标准委员会不想处理的杂乱细节。
推荐阅读
- javascript - 如何在使用 setTimeout 函数时停止循环
- mysql - 杀死进程(数字海洋 ubuntu 液滴)
- vue.js - VUE i18n 中长文本段落的国际化
- sql-server - 如何使用来自命令提示符的插入/选择查询执行 SQL Server Management Studio 上可用的存储过程
- python - 无法使用 Flask 在 PostgreSQL 中创建多个表
- python - PyQT5:无法让路径变量在其函数之外工作
- react-native - React-Native:右对齐的选择器数据
- django - 从 django 管理表单中的编辑表单一对一关系中排除分配的对象
- java - 在给定角度和距点的距离的情况下找到坐标
- python - 如何在 SQL 中进行内部联接时添加带有条件的常量列