Я хочу включить некоторые std::ostringstream
объекты в моей программе для регистрации и сообщения об ошибках. На основе параметров, заданных во время компиляции, потоки журнала и ошибок либо будут собирать свои соответствующие данные (для сохранения или чего-либо другого), либо они будут перенаправлены на std::cout
а также std::cerr
(для целей отладки). Насколько я могу судить по Рекомендации (а также Вот) Я смотрел на, std::ostringstream
объекты наследуют rdbuf()
метод, и я должен быть в состоянии вызвать rdbuf()
метод объекта потока, передавая в качестве аргумента указатель на std::streambuf
ассоциировать с потоками.
Тем не менее, когда я пытаюсь скомпилировать, я получаю сообщение об ошибке при отсутствии соответствующего вызова функции, с rdbuf()
метод без каких-либо аргументов, перечисленных в качестве кандидата.
Ошибка, которую я получаю от g ++ (4.6.3 в Ubuntu 12.04 x86_64):
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 [с _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 1class 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 );
}
}
Если бы кто-нибудь мог помочь мне решить эту проблему или предложить альтернативный метод с учетом того, что я пытаюсь сделать, я был бы признателен.
std::ostringstream
объекты наследуютrdbuf()
метод, и я должен быть в состоянии вызватьrdbuf()
метод объекта потока, передавая в качестве аргумента указатель наstd::streambuf
ассоциировать с потоками.
Вы должны с точки зрения Принцип подстановки Лискова, но ты не можешь.
std::basic_stringstream::rdbuf
скрывает обе подписи std::basic_ios::rdbuf()
, Вы можете вызывать их с некоторыми уродливыми кастами, но я думаю, что это не будет иметь никакого эффекта. Строковый поток всегда гарантирует запись в строковый буфер.
Других решений пока нет …