2

I need to convert std::string to std::wstring. I have used something on below lines with visual studio 2010 (and it's working fine) :-

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string narrow = converter.to_bytes(wide_utf16_source_string);
std::wstring wide = converter.from_bytes(narrow_utf8_source_string);

However, when I build it on gcc 4.3.4, it gives error :-

  .cxx:333: error: 'wstring_convert' is not a member of 'std'
  .cxx:333: error: 'codecvt_utf8_utf16' is not a member of 'std'

Can anyone please provide me some way to do this conversion in platform independent way.

ravi
  • 10,994
  • 1
  • 18
  • 36
  • Have you seen [this post](http://stackoverflow.com/questions/15615136/is-codecvt-not-a-std-header). One of the answers suggests using Boost.Locale. – Mohamad Elghawi Apr 26 '16 at 11:19
  • Yes...And that's why I asked for solution rather than asking reason for this behaviour. – ravi Apr 26 '16 at 11:20
  • 1
    Since `std::wstring` is `std::basic_string< wchar_t >`, and `wchar_t` itself is not portably defined (16 bits on Windows, 32 bits basically everywhere else), I'd say you should rather be looking at `std::u16string`, which *is* portably defined, including the encoding used... or, even better, [use ICU](http://stackoverflow.com/questions/313970/how-to-convert-stdstring-to-lower-case/24063783#24063783) because even `u16string` isn't perfect. – DevSolar Apr 26 '16 at 11:21
  • The above being said, using an up-to-date version of GCC and libstdc++ should solve the immediate problem with ``. – DevSolar Apr 26 '16 at 11:25
  • 1
    You will need to use G++ 5.1 or later – M.M Apr 26 '16 at 11:31
  • How portable do you need this to be and can you use any 3rd party libraries? Your above code should work on any C++11 compliant compiler. – NathanOliver Apr 26 '16 at 11:52
  • @NathanOliver My ideal solution would be to support it on c++03 compiler without using any 3rd party libraries. But it would be helpful for me if you could provide your approaches even with 3rd party libs. – ravi Apr 26 '16 at 12:03
  • @ravi Well if you can use boost then this: http://stackoverflow.com/a/28875347/4342498 – NathanOliver Apr 26 '16 at 12:05
  • Look at the answer [here](http://stackoverflow.com/a/38834455/3001953). – Maks Aug 08 '16 at 16:42
  • @M.M I am on gcc 6.2 and I cannot use codecvt. –  May 08 '17 at 17:58
  • If you want portability, don't assume that wchar_t is utf_16, because it isn't. – n. m. could be an AI Sep 23 '20 at 05:51
  • `std::wstring_convert` and `std::codecvt_utf8_utf16` are C++11 features and C++11 is only fully supported since GCC 4.8.1. Both have been deprecated since C++17 so don't use them – phuclv Sep 23 '20 at 06:43

1 Answers1

1
#include <codecvt>
#include <locale>

// utility wrapper to adapt locale-bound facets for wstring/wbuffer convert
template<class Facet>
struct deletable_facet : Facet
{
    template<class ...Args>
    deletable_facet(Args&& ...args) : Facet(std::forward<Args>(args)...) {}
    ~deletable_facet() {}
};

std::string wstr2str(const wchar_t* wstr) {
    std::wstring source(wstr);
    std::wstring_convert<deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>, wchar_t> convert;
    std::string dest = convert.to_bytes(source);  
    return dest;
}

Based on https://en.cppreference.com/w/cpp/locale/codecvt example.

Eugene Gr. Philippov
  • 1,908
  • 2
  • 23
  • 18