4

我想std::ostringstream在我的程序中包含一些对象以用于记录和错误报告的目的。根据编译时给定的设置,日志和错误流将收集它们各自的数据(要保存或其他),或者它们将被重定向到std::coutstd::cerr(用于调试目的)。据我从参考资料(和这里)可以看出,std::ostringstream对象继承了该rdbuf()方法,并且我应该能够rdbuf()在流对象上调用该方法,将指针作为参数传递给与std::streambuf流相关联的指针。

但是,当我尝试编译时,我收到一个错误,因为没有匹配的函数调用,rdbuf()没有任何参数的方法被列为候选。

我从 g++ 得到的错误(Ubuntu 12.04 x86_64 上的 4.6.3):

sigma@SigmaSys:~/Scripts/http/test$ g++ test.cc -c -o test.o
test.cc:在构造函数'Logger::Logger()'中:
test.cc:23:43: 错误: 没有匹配函数调用'std::basic_ostringstream::rdbuf(std::basic_streambuf*)'
test.cc:23:43: 注意:候选人是:
/usr/include/c++/4.6/sstream:449:7: 注意:std::basic_ostringstream::__stringbuf_type* std::basic_ostringstream::rdbuf() const [with _CharT = char, _Traits = std::char_traits, _Alloc = std::allocator, std::basic_ostringstream::__stringbuf_type = std::basic_stringbuf]
/usr/include/c++/4.6/sstream:449:7:注意:候选人需要 0 个参数,提供 1 个

这是源文件和头文件的精简版本:

http_utils.h

#include <string>
#include <sstream>
#include <streambuf>

#define HTTP_DEBUG_MODE 1


class Logger {
    private:
        static std::ostringstream errOut;
        static std::ostringstream logOut;

        static std::streambuf* cerrStreamBuffBackup;
        static std::streambuf* coutStreamBuffBackup;

        static std::streambuf* errOutStreamBuffBackup;
        static std::streambuf* logOutStreamBuffBackup;
    public:
        Logger();
        ~Logger();
};

http_utils.cc

#include "test.h"
#include <string>
#include <iostream>
#include <sstream>
#include <streambuf>


std::ostringstream Logger::errOut;
std::ostringstream Logger::logOut;
std::streambuf* Logger::cerrStreamBuffBackup = NULL;
std::streambuf* Logger::coutStreamBuffBackup = NULL;
std::streambuf* Logger::errOutStreamBuffBackup = NULL;
std::streambuf* Logger::logOutStreamBuffBackup = NULL;


Logger::Logger() {
    if (HTTP_DEBUG_MODE) {//Redirect logging/error to stdout/stderr
        Logger::errOutStreamBuffBackup = Logger::errOut.rdbuf();
        Logger::logOutStreamBuffBackup = Logger::logOut.rdbuf();

        Logger::errOut.rdbuf( std::cerr.rdbuf() );
        Logger::logOut.rdbuf( std::cout.rdbuf() );
    } else {//Redirect stdout/stderr to custom logging/error functionality
        cerrStreamBuffBackup = std::cerr.rdbuf();
        coutStreamBuffBackup = std::cout.rdbuf();

        std::cerr.rdbuf( errOut.rdbuf() );
        std::cout.rdbuf( logOut.rdbuf() );
    }
}
Logger::~Logger() {
    if (HTTP_DEBUG_MODE) {

    } else {//Restore stdout/stderr streambuf
        std::cerr.rdbuf( Logger::cerrStreamBuffBackup );
        std::cout.rdbuf( Logger::coutStreamBuffBackup );
    }
}

如果有人可以帮我解决这个问题,或者根据我正在尝试做的事情提出替代方法,我将不胜感激。

4

1 回答 1

2

std::ostringstream对象继承该rdbuf()方法,我应该能够rdbuf()在流对象上调用该方法,将指针作为参数传递给与std::streambuf流关联的指针。

你应该根据Liskov 替换原则,但你不能。

std::basic_stringstream::rdbuf隐藏std::basic_ios::rdbuf(). 你可以用一些丑陋的演员来称呼他们,但我认为这没有效果。字符串流始终保证写入字符串缓冲区。

于 2013-03-30T18:24:30.173 回答