<&书信电报;C+中的运算符重载+;用于记录目的 我有一个C++类,在这里我放置了很多STD::CUT语句来打印有关这个类正在处理的大量信号的信息性文本消息。我的目的是将这些文本消息重定向到名为log的函数。在这个函数中,我有一个名为mVerbose的标志,它定义了是否应该打印日志文本。该功能的内容如下: void XXXProxy::log(std::stringstream& ss) { if(mVerbose) { std::cout << ss; ss << ""; } } void XXXProxy::log(std::stringstream&ss) { if(mVerbose) { std::cout

<&书信电报;C+中的运算符重载+;用于记录目的 我有一个C++类,在这里我放置了很多STD::CUT语句来打印有关这个类正在处理的大量信号的信息性文本消息。我的目的是将这些文本消息重定向到名为log的函数。在这个函数中,我有一个名为mVerbose的标志,它定义了是否应该打印日志文本。该功能的内容如下: void XXXProxy::log(std::stringstream& ss) { if(mVerbose) { std::cout << ss; ss << ""; } } void XXXProxy::log(std::stringstream&ss) { if(mVerbose) { std::cout,c++,c++11,operator-overloading,C++,C++11,Operator Overloading,如果您不想直接使用std::cout并且希望拥有自己的日志类,那么可以实现一个简单的包装器,提供与std::ostream相同的接口:操作符示例的时间戳仅此而已,示例:) 但如果您喜欢,我们可以尝试实现它。感谢C++11及其STL的巨大改进,我们有一个优秀的时间/日期API: std::chrono基于三个方面: 时钟 持续时间 时间点 此外,chrono提供了三种类型的时钟,std::system\u clock,std::stable\u clock,和std::high\u resol

如果您不想直接使用
std::cout
并且希望拥有自己的日志类,那么可以实现一个简单的包装器,提供与
std::ostream
相同的接口:操作符示例的时间戳仅此而已,示例:)

但如果您喜欢,我们可以尝试实现它。感谢C++11及其STL的巨大改进,我们有一个优秀的时间/日期API:

std::chrono
基于三个方面:

  • 时钟
  • 持续时间
  • 时间点
此外,chrono提供了三种类型的时钟,
std::system\u clock
std::stable\u clock
,和
std::high\u resolution\u clock
。在我们的例子中,我们使用
std::system\u clock
(我们希望访问日期时间,而不是测量精确的时间间隔)。
有关std::chrono的更多信息,请签出

因此,如果我们必须为日志头实现时间戳,我们可以这样做:

<> > >编辑:像其他好东西一样,C++模板是很好的工具,直到你过度使用它。 我们的问题是,
std::endl
是一个模板函数,所以我们不能将它直接传递给
将其他模板化函数作为参数(
operator你想用什么?
XXXProxy
似乎违反了单一责任的原则。当写非成员
@balki是的,这是真的。我不知道为什么我在这个答案xD中将它写为全局。我总是把它作为类范围中的非成员朋友来写。@Fardaarda你问,我们试图帮助你。这就是stackoverflow:)如果您有任何问题,请在这里发表评论。这次是stampmarker(日志输出(17:57))。我们如何使类日志能够为我们自动捕获它?还是应该由类的用户来管理它?Thnx。@Fardaarda评论回答bellow上面的代码示例没有编译。如果您能提供编译解决方案,我将不胜感激。谢谢。为什么在操作符的实现末尾没有
返回
etonn只是输入错误,很抱歉这几乎是正确的,您应该使用
Log&
作为返回签名从任何函数返回
*此
 logStr << "SE"
        << getAddr().toString()
        << ": WAITING on epoll..."
        << std::endl;      
 log(logStr);
 << "SE"
 << getAddr().toString()
 << ": WAITING on epoll..."
 << std::endl;      
 void XXXProxy::operator << (std::stringstream& ss)
 {
   if(mVerbose)
   {
     std::cout << ss;
     ss << "";
   }
 } 
class Log {
private: 
    std::ostream& _out_stream;

    //Constructor: User provides custom output stream, or uses default (std::cout).
    public: Log(std::ostream& stream = std::cout): _out_stream(stream) {} 

    //Implicit conversion to std::ostream
    operator std::ostream() {
        return _out_stream;
    } 

    //Templated operator>> that uses the std::ostream: Everything that has defined 
    //an operator<< for the std::ostream (Everithing "printable" with std::cout 
    //and its colleages) can use this function.    
    template<typename T> 
    Log& operator<< (const T& data) 
    {
        _out_stream << data;
    }
}
struct Foo
{
    int x = 0; //You marked your question as C++11, so in class initializers 
               //are allowed. 

    //std::ostream::operator<< overload for Foo:
    friend std::ostream& operator<<(std::ostream& os , const Foo& foo)
    {
        os << foo.x;
    }
};

int main()
{
  Log my_log;
  Foo my_foo;

  my_foo.x = 31415;

  my_log << my_foo << std::endl; //This prints "31415" using std::cout.
}
class Log
{
private:
    std::ostream& _out_stream;
    bool         _next_is_begin;

    const std::string _log_header;
    using endl_type = decltype( std::endl ); //This is the key: std::endl is a template function, and this is the signature of that function (For std::ostream).

public:
    static const std::string default_log_header;

    //Constructor: User passes a custom log header and output stream, or uses defaults.
    Log(const std::string& log_header = default_log_header , std::ostream& out_stream = std::cout) : _log_header( log_header ) , _out_stream( out_stream ) , _next_is_begin( true ) {}

    //Overload for std::endl only:
    Log& operator<<(endl_type endl)
    {
        _next_is_begin = true;

        _out_stream << endl;

        return *this;
    }

    //Overload for anything else:
    template<typename T>           
    Log& operator<< (const T& data) 
    {
        auto now        = std::chrono::system_clock::now();
        auto now_time_t = std::chrono::system_clock::to_time_t( now ); //Uhhg, C APIs...
        auto now_tm     = std::localtime( &now_time_t ); //More uhhg, C style... 

        if( _next_is_begin )
            _out_stream << _log_header << "(" << now_tm->tm_hour << ":" << now_tm->tm_min << ":" << now_tm->tm_sec << "): " << data;
        else
            _out_stream << data;

        _next_is_begin = false;

        return *this;
    }
};

const std::string Log::default_log_header = "Log entry";