使用 std::basic_string<t> 是否合理?作为目标 C++03 时的连续缓冲区?

2021-12-17 00:00:00 string winapi c++ stl c++03

我知道在 C++03 中,从技术上讲,std::basic_string 模板不需要具有连续内存.但是,我很好奇有多少现代编译器真正利用了这种自由的实现.例如,如果想使用 basic_string 来接收某些 C API 的结果(如下例所示),分配一个向量只是为了立即将其转换为字符串似乎很愚蠢.

I know that in C++03, technically the std::basic_string template is not required to have contiguous memory. However, I'm curious how many implementations exist for modern compilers that actually take advantage of this freedom. For example, if one wants to use basic_string to receive the results of some C API (like the example below), it seems silly to allocate a vector just to turn it into a string immediately.

示例:

DWORD valueLength = 0;
DWORD type;
LONG errorCheck = RegQueryValueExW(
        hWin32,
        value.c_str(),
        NULL,
        &type,
        NULL,
        &valueLength);

if (errorCheck != ERROR_SUCCESS)
    WindowsApiException::Throw(errorCheck);
else if (valueLength == 0)
    return std::wstring();

std::wstring buffer;
do
{
    buffer.resize(valueLength/sizeof(wchar_t));
    errorCheck = RegQueryValueExW(
            hWin32,
            value.c_str(),
            NULL,
            &type,
            &buffer[0],
            &valueLength);
} while (errorCheck == ERROR_MORE_DATA);

if (errorCheck != ERROR_SUCCESS)
    WindowsApiException::Throw(errorCheck);

return buffer;

我知道这样的代码可能会稍微降低可移植性,因为它意味着 std::wstring 是连续的――但我想知道这段代码是多么不可移植.换句话说,编译器如何真正利用非连续内存所允许的自由?

I know code like this might slightly reduce portability because it implies that std::wstring is contiguous -- but I'm wondering just how unportable that makes this code. Put another way, how may compilers actually take advantage of the freedom having noncontiguous memory allows?

我更新了这个问题以提及 C++03.读者应该注意,当以 C++11 为目标时,标准现在要求 basic_string 是连续的,因此当以该标准为目标时,上述问题不是问题.

I updated this question to mention C++03. Readers should note that when targeting C++11, the standard now requires that basic_string be contiguous, so the above question is a non issue when targeting that standard.

推荐答案

我认为假设 std::string 连续分配其存储空间是非常安全的.

I'd consider it quite safe to assume that std::string allocates its storage contiguously.

目前,std::string 的所有已知实现都是连续分配空间的.

At the present time, all known implementations of std::string allocate space contiguously.

此外,C++ 0x (N3000) 要求连续分配空间(第 21.4.1/5 节):

Moreover, the current draft of C++ 0x (N3000) requires that the space be allocated contiguously (§21.4.1/5):

在一个类似字符的对象应存储 basic_string 对象连续.也就是说,对于任意basic_string 对象 s,身份&*(s.begin() + n) == &*s.begin() + n应适用于 n 的所有值,这样0 <= n

The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().

因此,std::string 当前或未来实现使用非连续存储的可能性基本上为零.

As such, the chances of a current or future implementation of std::string using non-contiguous storage are essentially nil.

相关文章