std::wstring_view: ¿Mejor que const& en C++?

Fuentes: Why Don’t You Use String Views (as std::wstring_view) Instead of Passing std::wstring by const&?

En el mundo del C++, es común escuchar la recomendación de reemplazar el paso de std::wstring por referencia constante (const std::wstring&) con std::wstring_view para modernizar el código. Sin embargo, esta sugerencia puede ser incorrecta y generar errores sutiles, especialmente cuando se interactúa con APIs de Win32.

La clave del problema radica en cómo std::wstring y std::wstring_view manejan la terminación nula de las cadenas. Las APIs de Win32, a menudo, esperan cadenas Unicode UTF-16 terminadas en nulo (representadas como PCWSTR, que es un const wchar_t* terminado en nulo). std::wstring garantiza que el puntero devuelto por su método data() (o preferiblemente c_str()) apunte a una cadena terminada en nulo. En contraste, std::wstring_view no ofrece esta garantía; la cadena a la que apunta puede o no estar terminada en nulo. Usar std::wstring_view directamente con APIs de Win32 que requieren terminación nula puede llevar a comportamientos impredecibles y errores difíciles de depurar.

¿Por qué es importante? Imagina que una API de Win32 intenta leer la cadena hasta el final, esperando encontrar el carácter nulo. Si la cadena proporcionada por std::wstring_view no está terminada en nulo, la API podría leer más allá de los límites de la memoria asignada, causando un fallo o corrupción de datos.

Casos de uso: Esta situación es común en proyectos que interactúan con código heredado de Win32 o bibliotecas que esperan cadenas C-style. Desarrolladores que trabajan en aplicaciones de escritorio de Windows, drivers, o cualquier software que utilice APIs de bajo nivel de Windows se verán afectados.

Consideraciones: Si bien std::wstring_view es una herramienta valiosa para evitar copias innecesarias de cadenas en muchos contextos, no es un reemplazo universal para std::wstring& cuando se trata con APIs que requieren terminación nula. La mejor práctica es seguir utilizando std::wstring por referencia constante y, crucialmente, usar el método c_str() en lugar de data() para obtener el puntero a la cadena terminada en nulo. El uso de c_str() también proporciona una barrera de seguridad, ya que el compilador generará un error si intentas reemplazar std::wstring& con std::wstring_view y usas c_str() en el código modificado, previniendo así errores en tiempo de ejecución.