Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Init std::string with single copy

I have the following code in C++ on Win32. It's simply a C++ warp on some Win32 API that returns a CHAR *:

wstring expandEnvironmentVariables(const wstring & str)
{
    DWORD neededSize = ExpandEnvironmentStrings(str.c_str(), nullptr, 0);
    vector<WCHAR> expandedStr(neededSize);
    if (0 == ExpandEnvironmentStrings(str.c_str(), expandedStr.data(), static_cast<DWORD>(expandedStr.size()))) {
        return wstring(str);
    }
    return wstring(expandedStr.data());
}

What bothers me about this code, is the double copy of the result.

  1. by the API into a vector of WCHARs.
  2. from the vector into std::wstring.

Is there a way to implement this code with just a single copy, and without a major change to the signature of the function. This is a specific example, but I'm more interested in the general solution and the right way to work with std::wstring/std::string, because this pattern shows itself in many places in the code.

like image 419
Pagefault Avatar asked Mar 25 '26 16:03

Pagefault


1 Answers

Regarding the C++ side you can just use a wstring directly as a result variable.

To get a pointer to the buffer of a wstring of non-zero size, just use &s[0].

Just like std::vector, std::basic_string has a guaranteed contiguous buffer.

For the return it will probably get Return Value Optimization (RVO), and if not then it will be moved.

Disclaimer: I haven't checked the documentation of the API functions. I do not know if this code correct or even meaningful. I'm just assuming that.

like image 128
Cheers and hth. - Alf Avatar answered Mar 27 '26 05:03

Cheers and hth. - Alf