Última atualização:2026-10-12
C++17 std::string_view¶
0.Problema¶
string_view surgiu a partir do C++17 e, na prática, é o slice do leveldb; seu objetivo é evitar cópias de memória e oferecer um substr eficiente.
Porém, isso também introduz problemas de ponteiros e referências: como o string_view não possui a propriedade do conteúdo apontado, comparado com o Rust ele é apenas um empréstimo; se o objeto que possui o conteúdo for liberado antecipadamente, surgirá o problema de referência pendente (dangling). O Rust analisa em tempo de compilação o tempo de vida das variáveis, garantindo que os recursos emprestados não sejam liberados enquanto estão em uso. O C++, por sua vez, não faz essa verificação: é preciso garanti-la manualmente.
1.Implementação interna¶
string_view é um tipo basic_string_view; pode-se ver que _Traits usa o char_traits padrão, o que é muito importante, pois diversas funções adiante usam funções-membro de char_traits para executar as operações centrais.
template<class _CharT, class _Traits = char_traits<_CharT> >
class _LIBCPP_TEMPLATE_VIS basic_string_view;
typedef basic_string_view<char> string_view;
Membros internos do basic_string_view:
Construtores compatíveis com string e 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);
Suporte a 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;
Outras funções centrais:
- substr
- remove_prefix
- compare
- find
- ...
A partir do C++20, há suporte a starts_with, ends_with e contains; esses três já eram suportados desde o início no slice do 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.Armadilhas de uso¶
2.1 \0¶
O string_view não se preocupa com o \0; ele se importa com a quantidade real de caracteres.
Saída: s: 8 "abcdef"
Aqui o esperado seria imprimir hello, mas foi impresso apenas h.
2.2 Tempo de vida¶
Nesse exemplo, s saiu do escopo e o string_view tornou-se uma referência pendente.
Tempo de vida
O std::string_view não possui o armazenamento de caracteres subjacente; certifique-se de que o tempo de vida do objeto referenciado cubra todo o período de uso.
Tópicos relacionados¶
- Atributo [[nodiscard]] no C++17 | C++那些事
- Recursos de memória PMR no C++17 | C++那些事
- Dezessete funcionalidades avançadas do C++17 | C++那些事
- Dedução de argumentos de template de classe CTAD no C++17 | C++那些事
- C++17 optional_ref | C++那些事
- C++17 std::variant | C++那些事
- Vinculações estruturadas no C++17 | C++那些事
- Dedução com auto em templates no C++17 | C++那些事
- Templates de variável no C++17 | C++那些事