The benefit of c++11 is that all char strings are UTF-8:
This is not specified by C++11 for normal string literals and you'll find VC++ doesn't make it so. If you want UTF-8 strings then you have to ensure that yourself.
My understanding is that the wide version takes a 16bit wchar_t that in Windows land is UTF-16 and the ANSI version is ASCII.
The *A
functions always use the system code page which is an extended version of ASCII (and is never UTF-8).
Is the correct way to use this function to convert the std::string into UTF-16 (with std::codecvt_utf8_utf16 or something) then put in into the wide version of the function?
If you have ensured that your strings are UTF-8 (which is a good idea, IMO) then converting to UTF-16 and using the wchar_t
version is the correct thing to do.
#include <Windows.h>
#include <codecvt>
int main() {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
std::string var = "\xD0\xBA\xD0\xBE\xD1\x88\xD0\xBA\xD0\xB0"; // кошка
std::string val = "\xE6\x97\xA5\xE6\x9C\xAC\xE5\x9B\xBD"; // 日本国
SetEnvironmentVariableW(convert.from_bytes(var).c_str(),
convert.from_bytes(val).c_str());
}
With full C++11 conformance we could write std::string var = u8"кошка";
, however VC++ doesn't implement this and it appears to be a very low priority item since it doesn't appear explicitly on their roadmap to C++14 conformance.
Alternatively you can write std::string var = "кошка";
if you save your source code as "UTF-8 without BOM". Be aware that that method has caveats such as that you can't use wchar_t literals.