c++ - Logger for handling both wide and non-wide strings -


i want single logging function/macro similar cout/wcout, can take both std::string , std::wstring (and wchar_t, etc) input. wide inputs converted utf8 before being sent stream. ideally use it:

logger << utf8str << widestr << std::hex << 84 << " blah " << 1.2 << std::endl; 

a global overload of operator<< not work me, since collides other parts of project.

i'm trying extend std::ostringstream this:

#include <iostream> #include <sstream> #include <string>  #include <locale> #include <codecvt> using namespace std;  string wtoutf8(const wstring &wswide) {     typedef std::codecvt_utf8<wchar_t> convert_typex;     std::wstring_convert<convert_typex, wchar_t> converterx;     return converterx.to_bytes(wswide); }  struct clogstream : public virtual std::ostringstream {     // allow wstrings     clogstream& operator<< (const wstring& ws) { *this << wtoutf8(ws); return *this; }     // log wide string literals (e.g. l"widestr") , c-style wide strings strings instead of hex pointer address     clogstream& operator<< (const wchar_t* p_ws) { *this << wtoutf8(p_ws); return *this; }     // log wchar_t character instead of number     clogstream& operator<< (const wchar_t wc) { *this << wtoutf8(wstring(&wc,1)); return *this; } };  int main() {     string s("narrow ");     wstring ws(l"_wide_");      clogstream log;      // these seem work how want them     log << "narrow";     log << l"_wide_";     log << l"_wide_" << "narrow";     log << ws << l"_wide_";     log << s << "narrow";     log << ws << "narrow";     log << ws << s;      // here think maybe compiler uses ostream << instead of operator<< defined clogstream...     log << "narrow" << l"_wide"; // outputs wide string hex value (pointer string)     //log << s << ws;// won't compile - error: no match 'operator<<' (operand types 'std::basic_ostream<char>' , 'std::wstring {aka std::basic_string<wchar_t>}')      cout << log.str();/* output http://coliru.stacked-crooked.com/:     narrow_wide__wide_narrow_wide__wide_narrow narrow_wide_narrow_wide_narrow narrow0x4026d4*/ } 

this almost works me, except when wide input follows non-wide in same line, compiler stops using operator<< definition want to. explain why happening? there way prevent it, or approach use accomplish goal?

as suggested, tried defining stream operators non-members:

    clogstream& operator<< (clogstream& strm, const wstring& ws) { strm << wtoutf8(ws); return strm; }     clogstream& operator<< (clogstream& strm, const wchar_t* p_ws) { strm << wtoutf8(p_ws); return strm; }     clogstream& operator<< (clogstream& strm, const wchar_t wc) { strm << wtoutf8(wstring(&wc,1)); return strm; } 

but exact same output/compiler error.

here's solution ended using:

although works strings/wstrings, fails for:

  • things std::endl , other manipulators
  • numeric inputs, based on output, think interpreted wide characters.

-

#include <iostream> #include <sstream> #include <string>  #include <locale> #include <codecvt> using namespace std;  string wtoutf8(const wstring &wswide) {     typedef std::codecvt_utf8<wchar_t> convert_typex;     std::wstring_convert<convert_typex, wchar_t> converterx;     return converterx.to_bytes(wswide); }  // part avoid globally overloading std::ostringstream's operators, //  restriction elsewhere in project struct clogstream : public virtual std::ostringstream {        clogstream& operator<< (const wstring& ws) { *this << wtoutf8(ws); return *this; } // allow wstrings     clogstream& operator<< (const wchar_t* p_ws) { *this << wtoutf8(p_ws); return *this; } // c-style wide strings strings instead of hex pointer address     clogstream& operator<< (const wchar_t wc) { *this << wtoutf8(wstring(&wc,1)); return *this; } // wchar_t character instead of number };  // wrapping stream prevents output of clogstream& operator<< being interpreted std::ostringstream struct clogger {     clogstream s;     string str() { return s.str(); }      template <class t>     clogger& operator<<(t&& x) { s << std::forward<t>(x); return *this; } };  int main() {     string s("narrow");     wstring ws(l"_wide_");      clogger log;     log << "narrow" << l"_wide" << s << ws; //works     log << std::hex << 84; //won't compile     log << std::endl; //won't compile     log << std::setw(5); //won't compile     log << "1679.2='" << 1679.2 << "'"; //outputs character     log << "534='" << 534 << "'"; //outputs character      cout << "log=\n" << log.str() << "done" << endl; } 

Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -