clase std::string_view en C++17

El std::string tiene algunas desventajas, una de las situaciones más comunes son las strings constantes. A continuación se muestra el programa que demuestra el problema que se produce al tratar strings constantes con std::string:

Programa 1:

C++

// C++ program to demonstrate the
// problem occurred in string
#include <iostream>
#include <string>
using namespace std;
 
// Driver Code
int main()
{
    char str_1[]{ "Hello !!, GeeksforGeeks" };
 
    string str_2{ str_1 };
    string str_3{ str_2 };
 
    // Print the string
    cout << str_1 << '\n'
         << str_2 << '\n'
         << str_3 << '\n';
 
    return 0;
}

 
 Producción:

Output#1

Explicación: El resultado es el mismo que se esperaba. Pero, para ver «Hello !!, GeeksforGeeks» dos veces , std::string realiza sobrecargas en la memoria dos veces. Pero aquí la tarea era leer la string («¡¡Hola!!, GeeksforGeeks») , y no se requiere ninguna operación de escritura en ella. Entonces, solo para mostrar una string, ¿por qué asignar memoria varias veces? Para manejar las strings de forma más eficiente, C++17 propuso std::string_view() que proporciona la vista de char str[] predefinido sin crear un nuevo objeto en la memoria.

Inconveniente de std::string : En el ejemplo anterior, la misma string str_1 se imprime dos veces asignando dos variables de string diferentes. Entonces, para las variables str_2 y str_3 , la memoria se asignó usando la asignación de memoria estática , y eso causa una sobrecarga en nuestra memoria dos veces.

Beneficios de std::string_view : 

  • Ligero y más barato: std::string_view es muy ligero, más barato y se utiliza principalmente para proporcionar la vista de la string. Cada vez que se crea string_view , no hay necesidad de copiar la string de la manera que se hizo en el ejemplo anterior que era ineficiente y estaba causando una sobrecarga en la memoria. Hace que el proceso de copia de la string sea bastante eficiente y nunca crea ninguna copia de la string cuando la modificación se realiza en la string vista, los cambios realizados han aparecido en std::string_view .
  • Mejor rendimiento: std::string_view es mejor que const std::string& porque elimina la restricción de tener un objeto std::string al principio de la string, ya que std::string_view se compone de dos elementos, el primero es const char* que apunta a la posición inicial de la array y el segundo es size .
  • Admite funciones cruciales: std::string_view admite principalmente todas las funciones cruciales que se aplican sobre std::string como substr , compare, find, operadores de comparación sobrecargados (p. ej., ==, <, >, !=) . Entonces, en la mayoría de los casos, elimina la restricción de tener una declaración de objeto std::string cuando nuestra preferencia es de solo lectura.

std::string_view : la biblioteca C++17 ha propuesto un tipo estándar de string ( std::string_view ) que es diferente del std::string habitual. 

  • std::string_view proporciona un objeto liviano que ofrece acceso de solo lectura a una string o parte de una string usando una interfaz similar a la interfaz de std::_string y simplemente se refiere a la secuencia de caracteres contigua. A diferencia de std::string, que conserva su propia copia de la string, también proporciona una vista de una string que se define en otra parte del código fuente.
  • se compone de dos miembros: un const char* que apunta al inicio de la array char y el _size. Es una referencia no propietaria a una string en sí misma.
  • Se define en el encabezado (#include <string_view>) y la plantilla de clase std::string_view es la siguiente:

template<class CharT, class Traits = std::char_traits<CharT>> class basic_string_view;

La plantilla de clase string_view explica acerca de un objeto que puede hacer referencia a una secuencia contigua constante de char o una array de objetos similares a char con el primer elemento de la secuencia en la posición cero.

A continuación se muestra la versión exacta del código fuente anterior usando std::string_view :

Programa 2: 

C++

// C++ program to implement
// the above approach
#include <iostream>
using namespace std;
#include <string_view>
 
// Driver code
int main()
{
    // View the text "hello", which is
    // stored in the binary
    string_view str_1{ "Hello !!, GeeksforGeeks" };
 
    // View of the same "hello"
    string_view str_2{ str_1 };
 
    // View of the same "hello"
    string_view str_3{ str_2 };
 
    std::cout << str_1 << '\n' << str_2 << '\n' << str_3 << '\n';
    return 0;
}

Producción-

Output#1

Explicación: La salida sería la misma que la anterior, pero no se crean más copias de la string “¡¡Hola!!, GeeksforGeeks” en la memoria.

Parámetros en std::string_view :

Tipo de caracteres:
el tipo de caracteres define el tipo de caracteres que se almacenan en string_view. La biblioteca estándar de C++ proporciona las siguientes definiciones de tipo para las especializaciones de la plantilla descrita anteriormente.

  1. string_view para elementos de tipo char
  2. wstring_view , para wchar_t
  3. u16string_view para char16_t
  4. u32string_view para char32_t

A continuación se muestra el programa C++ para ilustrar el tipo Char:

Programa 3:

C++

// C++ program for the above approach
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
 
string_view sur_name(wstring_view x)
{
    return x.substr(6);
}
 
// Driver Code
int main()
{
    // Basic_string_view<wchar_t> wstr
    // (L"Madhav_Mohan"); both are equivalent
    const wchar_t* str1{ L"Madhav_Mohan" };
 
    cout << your_name(str1);
 
    return 0;
}

 
Producción- 

Output#4

Ejemplo de std::string_view: Los siguientes ejemplos muestran que la mayoría de las funciones basadas en strings se pueden usar con std::string_view como se usa str.compare() , str.back() , str.cend() y str. en() funciones.

Programa 4: 

C++

// C++ program to implement
// the above approach
#include <iostream>
#include <string_view>
using namespace std;
 
string to_alpha(int r)
{
    if (r < 0)
        return " less than ";
    else if (r == 0)
        return " equal to ";
    else
        return " greater than ";
}
 
// Driver code
int main()
{
    char str{ "Muddy" };
    char str_1{ "Maddy" };
 
    string_view str_2{ str_1 };
 
    // This line prints Maddy
    cout << str_2 << '\n';
 
    // Change 'M' to 'D' in arr
    str_1[0] = 'D';
 
    // This line prints Daddy
    cout << str_2 << '\n';
 
    cout << str_2.at(2);
    cout << str_2.back();
    cout << " is last char of str_2 is y " << (str_2.back() == 's');
    cout << " is last char of str_2 is y " << boolalpha << (str_2.back() == 's');
 
    // In above statement boolalpha is
    // used to  give the boolean result
    // in True or False
 
    int cmp{ str_1.compare(str_2) };
 
  cout << to_alpha(cmp
};
int cmp_1 = str.compare(1, 4, str_2);
cout << "last three characters of str are" << to_alpha(cmp_1) << "str_2.\n";
return 0;
}

 
Producción: 

Output#2

Modificación de std::string_view : en C++20 se han agregado algunas funciones nuevas como str.remove_suffix(), str.remove_suffix() usando estas funciones puede modificar std::string_view. Me gusta puede eliminar el sufijo selectivo o los prefijos de la string dada.

Programa 5: 

C++

// C++ program to implement
// the above approach
#include <iostream>
#include <iterator>
#include <string_view>
using namespace std;
 
// Driver code
int main()
{
    string_view str_1{ "Maddy" };
    cout << str_1 << '\n';
 
    string_view str_2{ "Daddy" };
    cout << str_2 << '\n';
 
    string_view var{ "Hello !!, GeeksforGeeks" };
    cout << var << '\n';
 
    cout << var.starts_with("Hi !!") << '\n';
    cout << var.ends_with("GeeksforGeeks !!") << '\n';
 
    // Remove the first characters.
    str_1.remove_prefix(1);
    cout << str_1 << '\n';
 
    // Remove the last 2 characters.
    str_1.remove_suffix(2);
    std::cout << str_1 << '\n';
 
    return 0;
}

Producción: 

Output#3

A continuación se muestra el ejemplo de algunas otras operaciones que se pueden realizar con std::string_view:

Programa 6: 

C++

// C++ program to implement the
// above approach
#include <array>
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>
using namespace std;
 
// Driver code
int main()
{
    constexpr string_view str{ "Daddy" };
    constexpr string_view str1{ "Maddy" };
    string str2{};
 
    // Copy data of str1 into str2
    str1.copy(str2.data(), 4);
 
    // This line prints Madddy
    cout << str2.data() << '\n';
 
    if ((str.compare(str2)) != 0)
        cout << str << " "
             << "doesn't = to"
             << " " << str1 << '\n';
    cout << str1.starts_with("Mad");
    cout << '\n'
         << str.starts_with("Pad") << '\n';
    cout << str1.ends_with("ddt");
    cout << '\n'
         << str.ends_with("ddy") << '\n';
 
    // Checks whether the given string contains
    // the given substring or character
    constexpr string_view s1{ "Hello! Madhav" };
 
    // Position of the first character that
    // match first
    constexpr string_view str3{ "Hi! Maddy" };
 
    size_t found = str3.find(str1);
    cout << found << '\n';
 
    // Find the last occurrence of a substring
    cout << '\n'
         << str3.rfind('d');
 
    // Gives the first time occurred char's position
    cout << '\n'
         << str3.find_first_of("d");
 
    // Gives the last time occurred char's position
    cout << '\n'
         << str3.find_last_of("d");
 
    // Finds the first char that's not equal to
    // any of the char(s) in the given string
    cout << '\n'
         << str3.find_last_not_of(str, 6);
 
    // It givesIndex of first unmatched character
    // when successful or string::npos if no such
    // character found. It searches for the first
    // char that doesn't match any of the char(s)
    // that has given in the argument
    cout << '\n'
         << str3.find_last_not_of(str, 4);
 
    return 0;
}

Producción:

Output#4

Strings terminadas no nulas : a diferencia de las strings C y std::string, que necesitan un terminador de string (‘\ 0’) al final de una string, std::string_view no necesita terminadores nulos para marcar el final de la string. Porque mantiene un registro de la longitud de la string. 

A continuación se muestra el programa C++ para implementar el enfoque anterior:

Programa 7:

C++

// C++ program to implement
// the above approach
#include <iostream>
 
// For std::size
#include <iterator>
#include <string_view>
using namespace std;
 
// Driver code
int main()
{
    // No null-terminator.
    char name[]{ 'M', 'a', 'd',
                 'h', 'a', 'v' };
 
    // Here name isn't null-terminated.
    // We need to pass the length manually.
    // Because name is an array, we can
    // use std::size to get its length.
    string_view str_1{ \name, size(name) };
 
    // This is safe and cout knows how to
    // print std::string_views.
    cout << str_1 << '\n';
 
    return 0;
}

Producción: 

Output#5

Conversión de std::string_view en std::string : se deben usar métodos de conversión explícitos porque la conversión implícita no ayudará aquí.

A continuación se muestra el programa C++ para implementar la conversión de std::string_view a std::string:

Programa 8: 

C++

// C++ program to implement
// the above approach
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
 
void print(string s)
{
    cout << s << '\n';
}
 
// Driver code
int main()
{
    string_view str_1{ "Madhav" };
    str_1.remove_suffix(3);
 
    // compile error: won't implicitly
    // convert
    // print(str_1);
 
    // explicit conversion
    string str_2{ str_1 };
 
    print(str_2);
 
    // It'll work
    print(static_cast<string>(str_1));
 
    return 0;
}

Producción:

Output#6

 Conversión de std::string_view a string de estilo C: funciones como strlen(), estas funciones necesitan una string de estilo C para ser utilizadas. Por lo tanto, siempre que sea necesario convertir un std::string_view en una string de estilo C, puede hacerlo convirtiéndolo primero en un std::string.

A continuación se muestra el programa C++ para implementar el enfoque anterior:

Programa 9:

C++

// C++ program to implement
// the above approach
#include <cstring>
#include <iostream>
#include <string>
#include <string_view>
 
// Driver code
int main()
{
    string_view str_1{ "Madhav" };
    str_1.remove_suffix(3);
 
    // Create a std::string from
    // the std::string_view
    string str_2{ str_1 };
 
    // A Null_terminated C-style string.
    auto Null_Terminated{ str_2.c_str() };
 
    // Pass the null-terminated string
    // to the function that we want to use.
    cout << str_2 << " has " << strlen(Null_Terminated) << " letter's\n";
 
    return 0;
}

Producción:

Output#7

 Problemas de alcance con std::string_view: std::string_view proporciona una vista, por lo que permanece independiente de una string de la que proporciona una vista, y proyecta la vista de la string a menos que la string vista esté dentro del alcance, pero en caso de que el alcance de las strings vistas se apaga, luego std::string_view no tiene nada que proyectar, por lo que muestra un comportamiento indefinido. std::string_view siempre necesita un literal de string o una string que ha sido creada por un std::string dentro del alcance para proyectar la vista de la string, pero tan pronto como el alcance muere, std::string_view no puede crear ninguna string por sí mismo porque es solo una vista.

A continuación se muestra el ejemplo para implementar el enfoque anterior:

Programa 10:

C++

// C++ program to implement
// the above approach
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
 
string_view ask_name()
{
    cout << "Write your surname?\n";
 
    // A std::string is needed, because
    // std::cin needs to modify it.
    string str_1{};
    cin >> str_1;
 
    // Pass str_1 to std::string_view
    string_view str_2{ str_1 };
 
    cout << str_2 << '\n';
 
    // str_1 dies, and so does the
    // string that str created.
    return str_2;
}
 
// Driver code
int main()
{
    std::string_view str_2{ ask_name() };
 
    // str_2 is observing a string that
    // already died.
 
    // Undefined behavior you'll observe
    cout << your surname is << str_2 << '\n';
 
    return 0;
}

Producción:

Output#7

Ejecución de std::string_view con la función data(): La función data() escribe los caracteres de la string en una array. Devuelve un puntero a la array, obtenido de la conversión de string a la array. Su tipo de retorno no es una string C válida ya que no se agrega ningún carácter ‘\0’ al final de la array.

A continuación se muestra el programa C++ para implementar el enfoque anterior:

Programa 11:

C++

// C++ program to implement
// the above approach
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
#include <string_view>
 
// Driver code
int main()
{
    string str{ "Madhav_Mohan" };
    string_view str1{ str.data() };
    cout << str1 << endl;
    string_view str2{ str1.substr(6) };
    string_view str3{ str2 };
    cout << str3;
    return 0;
}

Producción:

Output#8

Funciones de no miembros:

   operator==
   operator!=                                    (has been removed in C++20)
   operator<                                     (has been removed in C++20)
   operator>                                     (has been removed in C++20)
   operator<=                                    (has been removed in C++20)
   operator>=                                    (has been removed in C++20)
   operator<=>                                   (has newly been included C++20)

Nota : Std::string_view solo se ejecuta en C++ 17 o en versiones anteriores. Hay una serie de funciones que se incorporan con std::string_view, algunas de ellas son nuevas (C++ 20) y otras son antiguas. A continuación, me refiero a la dirección web donde puede obtenerlos también en profundidad.

Publicación traducida automáticamente

Artículo escrito por madhav_mohan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *