如何创建像 std::cout 这样的函数?

iFa*_*bod 2 c++ debugging logging cout

我正在为我的项目创建自己的日志记录实用程序,我想创建一个类似于 iostream 的 std::cout 的函数,以记录到文件并打印到控制台。

这是我想要的:

enum
{
    debug, error, warning, info
};

LOG(level) << "test"; // level - from the above enum
Run Code Online (Sandbox Code Playgroud)

结果应该是这样的:

int iPlayerID = 1337;
LOG(info) << "Player " << iPlayerID << "Connected";
Run Code Online (Sandbox Code Playgroud)

[Thu Jan 29 18:32:11 2015] [info] Player 1337 Connected

jro*_*rok 6

std::cout不是一个函数,它是一个std::ostream重载类型的对象operator<<

您可以如何做的快速草图:

enum Level {
    debug, error, warning, info
};

struct Logger {
    std::ostream* stream;  // set this in a constructor to point
                           // either to a file or console stream
    Level debug_level;
public:
    Logger& operator<<(const std::string& msg)
    {
        *stream << msg; // also print the level etc.
        return *this;
    }

    friend Logger& log(Logger& logger, Level n);
    {
        logger.debug_level = n;
        return logger;
    }
};
Run Code Online (Sandbox Code Playgroud)

Ant 然后像这样使用它

Logger l;
log(l, debug) << "test";
Run Code Online (Sandbox Code Playgroud)


Jam*_*nze 5

技巧是LOG(level)返回一个特殊类型,其中包含指向std::ostream, 的指针并定义<<运算符。就像是:

class LogStream
{
    std::ostream* myDest;
public:
    LogStream( std::ostream* dest ) : myDest( dest ) {}

    template <typename T>
    LogStream& operator<<( T const& obj )
    {
        if ( myDest != nullptr ) {
            *myDest << obj;
        }
        return *this;
    }
};
Run Code Online (Sandbox Code Playgroud)

LOG(level)宏创建一个实例,如下所示:

#define LOG(level) LogStream( getLogStream( level, __FILE__, __LINE__ ) )
Run Code Online (Sandbox Code Playgroud)

当然,getLogStream可以在调用时插入它想要的任何信息(例如时间戳)。

您可能想在 的析构函数中添加刷新LogStream