Operator << - how to determine the last argument

I am writing out a journal class in C ++. This class is singleton. I want to add the logs this way:

Log::GetInstance() << "Error: " << err_code << ", in class foo";

Ok, and inside the log object, I want to save all this line during the last argument ("in class foo" in this example).

How to determine the last value <argument? & L; <a <b <is_this_last <possibly_this_is <or_not.

I do not use any end tags.

+5
source share
6 answers

You can solve this problem without using singleton. If you perform this function:

Log log()
{
    return Log();
}

You can add a log in much the same way as before:

log() << "Error: " << err_code << ", in class foo";

, Log . , , .

+17

, Log::GetInstance - . - , , .

+9

, < <.

template<typename T>
LogFindT operator<<(Log aLog, T const& data)
{
    // Put stuff in log.
    log.putStuffInLog(data);

    // now return the object to detect the end of the statement.
    return LogFindT(aLog);
}


struct LogFindT
{
    LogFindT(Log& aLog) : TheLog(aLog) {}
    Log& TheLog;
    ~LogFindT()
    {
        // Do stuff when this object is eventually destroyed
        // at the end of the expression.
    }
};

template<typename T>
LogFindT& operator<<(LogFindT& aLog, T const& data)
{
     aLog.TheLog.putStuffInLog(data);

     // Return a reference to the input so we can chain.
     // The object is thus not destroyed until the end of the stream.
     return aLog;
}
+4

, , , , , , std::endl.

Log iostream streambuf, << endl << flush . , , .

endl.

Log &operator<< ( Log &l, Log & (*manip)( Log & ) )
    { return manip( l ); } // generically call any manipulator

Log &flog( Log &l ) // define a manipulator "flush log"
    { l->flush(); return l; }

operator<<

struct Flog {} flog;

Log &operator<< ( Log &l, Flog )
    { l->flush(); return l; }
+4

. , . . .

, :

Log::Message( message_here );

std::string. , , .

+1

There is no good way to do what you want. C and C ++ are simply non-line-oriented languages. There is no larger unit, such as a “line of code” or anything else, as well as call chains combined anyway.

In C ++, the expression "a <b <c <d" is exactly equivalent to three separate calls to the <<operator, like this:

 t1 = a;
 t2 = t1.operator<<(b);
 t3 = t2.operator<<(c);
 t4 = t3.operator<<(d);

Why C ++ ostreams uses endl as an explicit end-of-line marker; there simply is no decent way to do it differently.

0
source

All Articles