Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
153 views
in Technique[技术] by (71.8m points)

c++ - Equivalent wstring operation?

i'm trying to do the same operation, but with a compatible code for visual c++ 2010:

wstring widen(string Str) {
    const size_t wcharCount = Str.size() + 1;
    vector<wchar_t> Buffer(wcharCount);

    return wstring{
        Buffer.data(),(size_t)MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), -1, Buffer.data(), (int)wcharCount);
    };
}

Specifically this:

return wstring{
    Buffer.data(),(size_t)MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), -1, Buffer.data(), (int)wcharCount);
};

How do i return a wstring, but with another way... because i'm getting errors, because the compiler i must use is older.

I also want to learn more about converting the code, compatible with older versions of Microsoft visual c++ (this case here, i want to compile this in 2010 version (and i have it)).

EDIT: As an useful to track errors:

|Line 5| error C2143: syntax error : missing ';' before '{'|

|Line 5| error C2275: 'std::wstring' : illegal use of this type as an expression|

question from:https://stackoverflow.com/questions/65647364/equivalent-wstring-operation

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For older (pre-C++11) compilers, use parenthesis (return wstring(...)) instead of braces (return wstring{...}), and also use std::vector::operator[] to access the allocated array, not std::vector::data() (which didn’t exist yet), eg:

return wstring(
    &Buffer[0], MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), -1, &Buffer[0], wcharCount)
);

That being said, the source std::string’s size is the wrong size to use for the std::vector. Call MultiByteToWideChar() twice - call it once with a NULL output buffer to calculate the necessary size, and then call it again to write to the buffer. And, you should be using the std::string’s actual size instead of -1 for the source buffer size.

wstring widen(const string &Str) {
    const int wcharCount = MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), Str.size(), NULL, 0);
    vector<wchar_t> Buffer(wcharCount);
    return wstring(
        &Buffer[0], MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), Str.size(), &Buffer[0], wcharCount)
    );
}

Note that in C++11 and later, it is safe to use a pre-sized std::wstring directly as the destination buffer, you don’t need the std::vector at all, because std::wstring is guaranteed to use a single contiguous block of memory for its character data. And even in earlier compilers, this is usually safe in practice (though NOT guaranteed) because most implementations use a contiguous block anyway for efficiency:

wstring widen(const string &Str) {
    const int wcharCount = MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), Str.size(), NULL, 0);
    wstring Buffer;
    if (wcharCount > 0) {
        Buffer.resize(wcharCount);
        MultiByteToWideChar(CP_UTF8, 0, Str.c_str(), Str.size(), &Buffer[0]/* or Buffer.data() in C++17 */, wcharCount);
    }
    return Buffer;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...