首页 > 解决方案 > 参数化自定义流操纵器 - 为什么重载“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()

标签: c++iostreammanipulators

解决方案


您要查找的重载仅为函数指针定义。

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

会打开一整个潘多拉魔盒,里面满是标准委员会不想处理的杂乱细节。


推荐阅读