Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 超载<&书信电报;运算符并将参数传递到std::cout_C++_Templates_C++11_Stdout_Ostream - Fatal编程技术网

C++ 超载<&书信电报;运算符并将参数传递到std::cout

C++ 超载<&书信电报;运算符并将参数传递到std::cout,c++,templates,c++11,stdout,ostream,C++,Templates,C++11,Stdout,Ostream,我想创建一个用于日志记录的类,其行为类似于std::cout,但会自动向流中插入附加信息 我想要的示例用法如下(现在不必关心对象和上下文类型,只需假设它们是std::string): 我一直在尝试: template<typename T> Logger& operator << (const T& msg){ std::cout << timestamp() << msg << std::endl <&l

我想创建一个用于日志记录的类,其行为类似于
std::cout
,但会自动向流中插入附加信息

我想要的示例用法如下(现在不必关心对象和上下文类型,只需假设它们是std::string):

我一直在尝试:

template<typename T>
Logger& operator << (const T& msg){
    std::cout << timestamp() << msg << std::endl << std::flush;
    return *this;
}
模板

Logger&operator您的代码不起作用的原因是您没有实现
operator如果您愿意,您当然可以重载流类,只要
operator
std::endl
已经刷新流。请参阅:请提供整个(精简但完整)代码以进行复制。然后,不要解释错误,也要引用它。很可能您正在临时或常量
记录器上使用它,或者尝试将重载函数(如
std::endl
)流式传输到其中,但是如果没有实际的代码和错误,这是不可能的。Loki,这几乎解决了我的问题,谢谢!
[timestamp] Event with object : [obj_desc] while in context : [this context][eol][flush]
template<typename T>
Logger& operator << (const T& msg){
    std::cout << timestamp() << msg << std::endl << std::flush;
    return *this;
}
Logger l;
l << "Event with object : " << obj << " while in context : " << context;
Logger l;
l.operator<<("Event with object : ").operator<<(obj).operaator<<(" while in context : ").operator<<(context);
struct LoggerStream
{
    std::ostringstream strm;

    struct Timestamp
    {
    };

    ~LoggerStream()
    {
        std::string s = strm.str();
        if (!s.empty())
            std::cout << s << std::flush;
    }

    LoggerStream& operator<< (const Timestamp &t)
    {
        strm << "[timestamp] "; // format this however you need
        return *this;
    }

    LoggerStream& operator<< (const object &obj)
    {
        strm << "[obj_desc]"; // format this however you need
        return *this;
    }

    LoggerStream& operator<< (const context &ctx)
    {
        strm << "[this context]"; // format this however you need
        return *this;
    }

    LoggerStream& operator<< (std::ostream&(*f)(std::ostream&))
    {
        if (f == (std::basic_ostream<char>& (*)(std::basic_ostream<char>&)) &std::flush)
        {
            std::string s = strm.str();
            if (!s.empty())
                std::cout << s << std::flush;
            strm.str("");
            strm.clear();
        }
        else
            strm << f;

        return *this;
    }

    template<typename T>
    LoggerStream& operator<< (const T& value)
    {
        strm << value;
        return *this;
    }
};

class Logger
{
    LoggerStream getStream()
    {
        LoggerStream strm;
        strm << Timestamp;
        return strm;
    }
};
Logger l;
l.getStream() << "Event with object : " << obj << " while in context : " << context;
...
l.getStream() << "Event with object : " << obj << " while in context : " << context;
...
Logger l;
LoggerStream strm = l.getStream();
strm << "Event with object : " << obj << " while in context : " << context << std::flush;
...
strm << Logger::Timestamp << "Event with object : " << obj << " while in context : " << context << std::flush;
...
struct Logger
{
    std::ostringstream strm;

    ~Logger()
    {
        std::string s = strm.str();
        if (!s.empty())
            std::cout << "[timestamp] " << s << std::flush;
    }

    Logger& operator<< (const object &obj)
    {
        strm << "[obj_desc]"; // format this however you need
        return *this;
    }

    Logger& operator<< (const context &ctx)
    {
        strm << "[this context]"; // format this however you need
        return *this;
    }

    Logger& operator<< (std::ostream&(*f)(std::ostream&))
    {
        if (f == (std::basic_ostream<char>& (*)(std::basic_ostream<char>&)) &std::flush)
        {
            std::string s = strm.str();
            if (!s.empty())
                std::cout << "[timestamp] " << s << std::flush;
            strm.str("");
            strm.clear();
        }
        else
            strm << f;

        return *this;
    }

    template<typename T>
    Logger& operator<< (const T& value)
    {
        strm << value;
        return *this;
    }
};
Logger() << "Event with object : " << obj << " while in context : " << context;
...
Logger() << "Event with object : " << obj << " while in context : " << context;
...
Logger l;
l << "Event with object : " << obj << " while in context : " << context << std::flush;
...
l << "Event with object : " << obj << " while in context : " << context << std::flush;
...
#include <iostream>
#include <iomanip>
#include <sstream>
#include <ctime>
#include <unistd.h>

#define logcout std::cout << timestamp()

std::string timestamp(void) {
    time_t now = time(0);
    struct tm *tmx = localtime(&now);
    std::ostringstream oss;
    oss << '['
        << (tmx->tm_year+1900)
        << '-'
        << std::setfill('0') << std::setw(2) << (tmx->tm_mon+1)
        << '-'
        << std::setfill('0') << std::setw(2) << (tmx->tm_mday)
        << ' '
        << std::setfill('0') << std::setw(2) << (tmx->tm_hour)
        << ':'
        << std::setfill('0') << std::setw(2) << (tmx->tm_min)
        << ':'
        << std::setfill('0') << std::setw(2) << (tmx->tm_sec)
        << "] ";
    return oss.str();
}

int main (int argc, char *argv[]) {
    logcout << "A slightly\n";
    sleep (5);
    logcout << "sneaky" << " solution\n";
    return 0;
}
[2015-05-26 13:37:04] A slightly
[2015-05-26 13:37:09] sneaky solution
#define logcout std::cout << timestamp()