c++ - ¿Puede std:: string overload "substr" for rvalue*this y robar recursos?
c++11 rvalue-reference (3)
Se me ocurrió que noté que la operación substr
std::string
podría ser mucho más eficiente para los valores cuando podría robar la memoria asignada de *this
.
La biblioteca estándar de N3225 contiene la siguiente declaración de función miembro de std::string
basic_string substr(size_type pos = 0, size_type n = npos) const;
¿Puede una implementación que pueda implementar un substr
optimizado para rvalues sobrecargar y proporcionar dos versiones, una de las cuales podría reutilizar el búfer para cadenas de rvalue?
basic_string substr(size_type pos = 0) &&;
basic_string substr(size_type pos, size_type n) const;
Me imagino que la versión de rvalue podría implementarse de la siguiente manera, reutilizando la memoria de *this
una configuración *this
a un estado de desde movido.
basic_string substr(size_type pos = 0) && {
basic_string __r;
__r.__internal_share_buf(pos, __start + pos, __size - pos);
__start = 0; // or whatever the ''empty'' state is
return __r;
}
¿Funciona esto de manera eficiente en implementaciones de cadenas comunes o esto requeriría demasiado mantenimiento?
En primer lugar, una implementación no puede agregar una sobrecarga que robe la fuente, ya que sería detectable:
std::string s="some random string";
std::string s2=std::move(s).substr(5,5);
assert(s=="some random string");
assert(s2=="rando");
La primera afirmación fallaría si la implementación robara los datos de s
, y la redacción de C ++ 0x esencialmente prohíba la copia en escritura.
En segundo lugar, esta no sería necesariamente una optimización de todos modos: tendría que agregar un servicio de limpieza adicional en std::string
para manejar el caso de que se trata de una subcadena de una cadena más grande, y significaría mantener bloques grandes cuando no hubiera ya no hay cadenas que hagan referencia a la cadena grande, solo algunas subcadenas de la misma.
Hay algunas clases de cadenas por ahí implementando copiar en escritura. Pero no recomendaría agregar otro tipo de cadena a su proyecto a menos que esté realmente justificado.
Echa un vistazo a la discusión en Cadenas de C ++ eficientes en memoria (internado, cuerdas, copia en escritura, etc.)
Sí, y tal vez debería ser propuesto al comité de estándares, o tal vez implementado en una biblioteca. Realmente no sé cuán valiosa sería la optimización. Y ese sería un estudio interesante por sí solo.
Cuando gcc aumenta el soporte para r-value this
, alguien debería intentarlo e informar de lo útil que es.