Última actualización:2026-10-12
C++17 std::string_view¶
0.Problema¶
string_view apareció a partir de C++17; en realidad no es más que el slice de leveldb, y su propósito es evitar las copias de memoria y conseguir un substr eficiente.
Sin embargo, también introduce problemas de punteros y referencias: como string_view no posee la propiedad del contenido al que apunta, en comparación con Rust se trata solo de un préstamo; si el objeto que posee el contenido se libera antes de tiempo, aparece el problema de la referencia colgante. Rust analiza en tiempo de compilación el ciclo de vida de las variables, garantizando que los recursos tomados en préstamo no se liberen mientras se usan. C++, en cambio, no realiza esta comprobación y hay que garantizarla manualmente.
1.Implementación interna¶
string_view es un tipo basic_string_view; puede verse que _Traits usa por defecto char_traits, algo muy importante: varias de las funciones posteriores ejecutan sus operaciones centrales mediante funciones miembro de char_traits.
template<class _CharT, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS basic_string_view;
typedef basic_string_view<char> string_view;
Miembros internos de basic_string_view:
La construcción es compatible con string y const char*
constexpr basic_string_view() noexcept;
constexpr basic_string_view(const basic_string_view&) noexcept = default;
basic_string_view& operator=(const basic_string_view&) noexcept = default;
template<class Allocator>
constexpr basic_string_view(const charT* str);
constexpr basic_string_view(const charT* str, size_type len);
Soporte de iteradores:
constexpr const_iterator begin() const noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr const_iterator cend() const noexcept;
const_reverse_iterator rbegin() const noexcept;
const_reverse_iterator rend() const noexcept;
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
Otras funciones esenciales:
- substr
- remove_prefix
- compare
- find
- ...
A partir de C++20 se soportan starts_with, ends_with y contains; estas tres ya estaban soportadas desde el principio en el slice de leveldb.
Literal string_view para char*:
constexpr basic_string_view<char> operator "" sv( const char *str, size_t len ) noexcept;
constexpr basic_string_view<wchar_t> operator "" sv( const wchar_t *str, size_t len ) noexcept;
constexpr basic_string_view<char16_t> operator "" sv( const char16_t *str, size_t len ) noexcept;
constexpr basic_string_view<char32_t> operator "" sv( const char32_t *str, size_t len ) noexcept;
2.Trampas de uso¶
2.1 \0¶
string_view no se ocupa de \0; lo que tiene en cuenta es el número real de caracteres.
Salida: s: 8 "abcdef"
Aquí lo que se espera mostrar es hello, pero se muestra h.
2.2 Ciclo de vida¶
En este ejemplo, cuando s sale del ámbito, string_view se convierte en una referencia colgante.
Ciclo de vida
std::string_view no posee el almacenamiento de caracteres subyacente: asegúrate de que el ciclo de vida del objeto referenciado cubra todo el periodo de uso.
Temas relacionados¶
- C++17: el atributo [[nodiscard]] | C++那些事
- Recursos de memoria PMR en C++17 | C++那些事
- Diecisiete características avanzadas de C++17 | C++那些事
- Deducción de argumentos de plantilla de clase CTAD en C++17 | C++那些事
- C++17 optional_ref | C++那些事
- C++17 std::variant | C++那些事
- Vinculaciones estructuradas en C++17 | C++那些事
- Deducción con auto en plantillas de C++17 | C++那些事
- Plantillas de variable en C++17 | C++那些事