tymczasowy problem ze strumieniem zwrotnym w strumieniu
Tworzę program rejestrujący z następującymi sekcjami:
// #define LOG(x) // for release mode
#define LOG(x) log(x)
log(const string& str);
log(const ostream& str);
Z pomysłem:
LOG("Test");
LOG(string("Testing") + " 123");
stringstream s;
LOG(s << "Testing" << 1 << "two" << 3);
To wszystko działa zgodnie z przeznaczeniem, ale kiedy to robię:
LOG(stringstream() << "Testing" << 1 << "two" << 3);
To nie działa:
void log(const ostream& os)
{
std::streambuf* buf = os.rdbuf();
if( buf && typeid(*buf) == typeid(std::stringbuf) )
{
const std::string& format = dynamic_cast<std::stringbuf&>(*buf).str();
cout << format << endl;
}
}
powoduje „format” zawierający niepotrzebne dane zamiast zwykłego poprawnego ciągu.
Myślę, że dzieje się tak, ponieważ tymczasowy ostream zwrócony przez operatora << przeżywa ciąg strumieniowy, z którego pochodzi.
Czy się mylę?
(Dlaczego string () działa w ten sposób? Czy dlatego, że zwraca referencję do siebie? Zakładam, że tak.)
Naprawdę chciałbym to zrobić w ten sposób, ponieważ eliminowałbym dodatkową alokację podczas logowania w trybie zwolnienia.
Wszelkie wskazówki lub sztuczki, aby to zrobić w ten sposób, zostaną przyjęte z zadowoleniem. W moim rzeczywistym rozwiązaniu mam wiele różnych funkcji dziennika i wszystkie są bardziej złożone niż to. Więc wolałbym, żeby to zostało zaimplementowane w kodzie wywołującym. (I nie modyfikując mojego #define, jeśli to możliwe)
Aby podać pomysł, przykład jednego z moich rzeczywistych #defines:
#define LOG_DEBUG_MSG(format, ...) \
LogMessage(DEBUG_TYPE, const char* filepos, sizeof( __QUOTE__( @__VA_ARGS__ )), \
format, __VA_ARGS__)
który pasuje do funkcji logarytmicznych typu printf, takich jak char *, string () i ostream (), a także funkcje inne niż vararg, przyjmujące string (), wyjątek () i HRESULT.