C ++: Is there a good way to read / write without specifying a character type in function names? (cout vs wcout etc.)

I had a problem getting a program to read from a file based on a template, for example:

bool parse(basic_ifstream<T> &file) { T ch; locale loc = file.getloc(); basic_string<T> buf; file.unsetf(ios_base::skipws); if (file.is_open()) { while (file >> ch) { if(isalnum(ch, loc)) { buf += ch; } else if(!buf.empty()) { addWord(buf); buf.clear(); } } if(!buf.empty()) { addWord(buf); } return true; } return false; } 

This will work when I create this class using <char> , but has problems when I use <wchar_t> (clearly).

Outside the class, I use:

 for (iter = mp.begin(); iter != mp.end(); ++iter ) { cout << iter->first << setw(textwidth - iter->first.length() + 1); cout << " " << iter->second << endl; } 

To write all the information from this data structure (this is a map<basic_string<T>, int> ), and, as predicted, cout explodes if iter->first not a char array.

I looked online and the consensus is to use wcout, but unfortunately, since this program requires that the template can be changed at compile time ( <char><wchar_t> ), I'm not sure how I can avoid just choosing cout or wcout. That is, if there is no way to read / write wide characters without changing a lot of code.

If this explanation sounds awkwardly complicated, let me know and I will address it as best as possible.

+4
source share
2 answers

Use a feature class. Instead of referencing directly to cout in the code, you should reference traits<T>::cout and then specialize traits<char> to std :: cout and traits<wchar_t> to wcout.

Update

 template <typename T> class traits { public: static std::basic_ostream<T>& tout; }; template<> std::ostream& traits<char>::tout = std::cout; template<> std::wostream& traits<wchar_t>::tout = std::wcout; int _tmain(int argc, _TCHAR* argv[]) { traits<char>::tout<<"Ascii"; traits<wchar_t>::tout<<L"Unicode"; return 0; } 
+6
source

Of course, just override the templates and use typedef:

 #ifdef USE_UNICODE typedef wchar_t tchar_t #else typedef unsigned char tchar_t #endif 

Then you can use the templates for most of the standard C ++ functions and containers:

 typedef std::basic_string<tchar_t> tstring 

and etc.

0
source

Source: https://habr.com/ru/post/1304319/


All Articles