是否可以像这样使操作员过载<<?

Is it possible to overload operator<< like this?

本文关键字:lt 操作员 像这样 是否      更新时间:2023-10-16

假设我有一个名为"Logger"的类。这个名字是不言自明的,它记录了东西。我有一个静态方法,它记录东西(记录器::log(字符串味精((。我想重载运算符<<,以便我可以执行以下操作:

    Logger << "AW YEAH, I LOVE C++";

我试图这样做,但不能。我管理的是:

    Logger l; 
    l << ":(";

我想做什么吗?如果是,如何?

提前谢谢你:)

如果Logger是一个类的名称,那么你当然不能这样做。使用类似的东西

Logger &log() {
    static Logger l;
    return l;
}
log() << "And the answer is" << 42;

假设你想利用std::ostream提供的输出运算符,你不应该尝试重载输出运算符!相反,您将创建一个合适的流缓冲区(即从 std::streambuf 派生的类(,并在该类的 overflow()sync() 方法中实现自定义输出逻辑。然后,记录器将从std::ostream派生并初始化其基类以使用自定义流缓冲区。

重载运算符对进行操作,而不是对类型进行操作。

也许你应该重命名你的类,然后创建一个合适的全局对象。例如:

logger.h:

class mylogger { /* ... */ };
extern mylogger logger;

记录器.cpp:

#include "logger.h"
mylogger logger;

用法:

#include "logger.h"
logger << "Done";

不过,要注意全局初始化问题;请查看您的std::cout实现,了解解决此问题的方法(例如,使用 Schwartz 计数器(。

这是可能的,但你需要弄清楚你真正想要的界面。一种选择是让你的Logger成为std::ostream(继承(,然后事情就会开箱即用。另一种方法是维护一个与std::ostream无关(无继承(的记录器,但随后您需要为要记录的任何和所有类型的T提供Logger& operator<<(Logger&,T const &)。对于std::string的特殊情况,您可以执行以下操作:

Logger& operator<<(Logger& logger, std::string const& msg) {
   logger.log(msg);               // need not be, and problably should be static
   return logger;
}

与大多数泛型代码一样,制作此泛型代码涉及C++模板的使用:

template <typename T>
Logger& operator<<(Logger& logger, T const & obj) {
   // do specific work based on the type, or a completely generic approach:
   std::ostringstream st;
   st << obj;
   logger.log(st.str());
   return logger;
}

在这一点上,您可能需要考虑添加对操纵器的支持,并且......好吧,如果您从这条路径开始,那么不在每个函数中创建std::ostringstream,而是创建一个函数作为成员,然后将所有数据转储到该流中并使用一些操纵器提取字符串并写入它(例如在std::flushstd::ends上......

template <typename T>
Logger& operator<<(Logger& logger, T const& obj) {
   logger.stream << obj;
   return logger;
}
Logger& operator<<(Logger& logger, std::ostream& (*manip)(std::ostream&)) {
   logger.stream << manip;
   if (manip == static_cast<std::ostream& (*)(std::ostream&)>(std::flush)) {
      logger.write(); // flush to disk
   }
   return logger;
}
// add support for other manipulators...

然后,您可能会开始怀疑从现成的日志记录库中取出一些并使用它是否更容易。