Sé que en C++ 03, técnicamente no es necesario que la plantilla std::basic_string
tenga memoria contigua. Sin embargo, tengo curiosidad de cuántas implementaciones existen para los compiladores modernos que realmente aprovechan esta libertad. Por ejemplo, si uno quiere usar basic_string
para recibir los resultados de alguna API de C (como en el ejemplo a continuación), parece tonto asignar un vector solo para convertirlo en una cadena inmediatamente.¿Es razonable usar std :: basic_string <t> como un búfer contiguo cuando se dirige a C++ 03?
Ejemplo:
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;
sé código como este podría reducir ligeramente la portabilidad, ya que implica que es contigua std::wstring
- pero me pregunto hasta qué punto no portables que hace este código. Dicho de otra manera, ¿cómo pueden los compiladores aprovechar la libertad que tiene la memoria no contigua?
EDIT: Actualicé esta pregunta para mencionar C++ 03. Los lectores deben tener en cuenta que al apuntar a C++ 11, el estándar ahora requiere que basic_string
sea contiguo, por lo que la pregunta anterior no es un problema al apuntar a ese estándar.
A menos que esté seguro de que MSVC le está proporcionando con éxito el RVO (aunque tiene dos devoluciones diferentes, una temporal y otra variable), entonces no se le "permite" preocuparse por una copia adicional; -) –
No creo que RVO pueda optimizar una copia entre el vector y la cadena .... –
Lo que quiero decir es que si el código actual no tiene RVO, entonces es "crear cadena. Copiarlo al valor de retorno". Estás hablando de un 50% más de copia si cambias eso a "crear vector. Cópialo a cadena".Cópielo para devolver el valor ". O tal vez no haga ninguna copia extra si lo hace' devuelva std :: wstring (vec.begin(), vec.end()); 'y obtenga" create vector. Copia para devolver el valor (a través de RVO) ". Me preocuparía si podía detectar la diferencia de velocidad antes de preocuparme por lo portátil que era el código resultante. Pero ese es solo el ejemplo, por eso es un comentario, no una respuesta. –