una sinonimo significa sentido rae qué que literalmente literal hablando figurado ejemplos dicen cuando conversacion c++ string c++14 user-defined-literals

c++ - sinonimo - Ventajas de usar literal definido por el usuario para cadenas en lugar de literal de cadena



sentido literal y figurado (4)

  1. Usar un literal de cadena C ++ significa que no necesitamos llamar a strlen para calcular la longitud. El compilador ya lo sabe.
  2. Podría permitir implementaciones de biblioteca donde los datos de cadena apuntan a la memoria en el espacio global utilizando literales C siempre deben forzar una copia de los datos a la memoria de almacenamiento en la construcción.

El tema de las cadenas en la Documentación SO solía decir, en la sección Comentarios:

Desde C ++ 14, en lugar de usar "foo" , se recomienda usar "foo"s , ya que s es un literal de cadena, que convierte el const char * "foo" en std::string "foo" .

La única ventaja que veo usando

std::string str = "foo"s;

en lugar de

std::string str = "foo";

es que en el primer caso el compilador puede realizar una copia de elisión (creo), que sería más rápido que la llamada del constructor en el segundo caso.

Sin embargo, esto está (todavía no) garantizado, por lo que el primero también podría llamar a un constructor, el constructor de copia.

Ignorando los casos en los que se requiere usar std::string literales como

std::string str = "Hello "s + "World!"s;

¿Hay algún beneficio de usar std::string literales std::string lugar de los literales const char[] ?


Además, UDL hace que sea más fácil tener /0 en la cadena

std::string s = "foo/0bar"s; // s contains a /0 in its middle. std::string s2 = "foo/0bar"; // equivalent to "foo"s


El consejo de usar "blah"s no tiene nada que ver con la eficiencia y todo con la corrección del código de principiante.

Los novatos de C ++ que no tienen experiencia en C, tienden a suponer que "blah" da como resultado un objeto de algún tipo de cadena razonable. Por ejemplo, para que uno pueda escribir cosas como "blah" + 42 , que funciona en muchos lenguajes de script. Con "blah" + 42 en C ++, sin embargo, uno solo incurre en Comportamiento indefinido, que se dirige más allá del final de la matriz de caracteres.

Pero si ese literal de cadena se escribe como "blah"s entonces uno obtiene un error de compilación, que es mucho más preferible.


Si eres parte de la multitud "Casi siempre automático", entonces el UDL es muy importante. Te permite hacer esto:

auto str = "Foo"s;

Y así, str será un std::string genuino, no un const char* . Por lo tanto, le permite decidir cuándo hacer qué.

Esto también es importante para la deducción del tipo de devolución automática:

[]() {return "Foo"s;}

O cualquier forma de deducción de tipo, realmente:

template<typename T> void foo(T &&t) {...} foo("Foo"s);

La única ventaja que veo usando [...] en lugar de [...] es que en el primer caso el compilador puede realizar una copia de elisión (creo), que sería más rápido que la llamada del constructor en el segundo caso.

Copy-elision no es más rápido que la llamada del constructor. De cualquier manera, estás llamando a uno de los constructores del objeto. La pregunta es cuál :

std::string str = "foo";

Esto provocará una llamada al constructor de std::string que toma un const char* . Pero dado que std::string tiene que copiar la cadena en su propio almacenamiento, debe obtener la longitud de la cadena para hacerlo. Y como no conoce la longitud, este constructor se ve obligado a usar strlen para obtenerlo (técnicamente, char_traits<char>::length , pero eso probablemente no será mucho más rápido).

Por el contrario:

std::string str = "foo"s;

Esto usará la plantilla UDL que tiene este prototipo:

string operator "" s(const char* str, size_t len);

Verá, el compilador conoce la longitud de un literal de cadena. Entonces, el código UDL pasa un puntero a la cadena y un tamaño. Y así, puede llamar al constructor std::string que toma un const char* y un size_t . Por lo tanto, no es necesario calcular la longitud de la cadena.

El consejo en cuestión no es que vayas y conviertas cada uso de un literal en la versión s . Si está de acuerdo con las limitaciones de una serie de caracteres, char . El consejo es que, si vas a almacenar ese literal en una std::string , es mejor hacerlo mientras todavía sea un literal y no un const char* .