c++ introducción - ¿Por qué es mejor la inicialización de la lista(usar llaves)que las alternativas?




código español (4)

MyClass a1 {a};     // clearer and less error-prone than the other three
MyClass a2 = {a};
MyClass a3 = a;
MyClass a4(a);

¿Por qué?

No pude encontrar una respuesta en SO, así que permítame responder mi propia pregunta.


Answers

Básicamente copiando y pegando desde "The C ++ Programming Language 4th Edition" de Bjarne Stroustrup:

La inicialización de la lista no permite el estrechamiento (§iso.8.5.4). Es decir:

  • Un entero no se puede convertir en otro entero que no pueda mantener su valor. Por ejemplo, char to int está permitido, pero no int to char.
  • Un valor de punto flotante no se puede convertir a otro tipo de punto flotante que no pueda mantener su valor. Por ejemplo, se permite flotar para duplicar, pero no para flotar.
  • Un valor de punto flotante no se puede convertir en un tipo entero.
  • Un valor entero no se puede convertir en un tipo de punto flotante.

Ejemplo:

void fun(double val, int val2) {

    int x2 = val; // if val==7.9, x2 becomes 7 (bad)

    char c2 = val2; // if val2==1025, c2 becomes 1 (bad)

    int x3 {val}; // error: possible truncation (good)

    char c3 {val2}; // error: possible narrowing (good)

    char c4 {24}; // OK: 24 can be represented exactly as a char (good)

    char c5 {264}; // error (assuming 8-bit chars): 264 cannot be 
                   // represented as a char (good)

    int x4 {2.0}; // error: no double to int value conversion (good)

}

La única situación en la que = se prefiere sobre {} es cuando se usa auto palabra clave auto para obtener el tipo determinado por el inicializador.

Ejemplo:

auto z1 {99}; // z1 is an initializer_list<int>
auto z2 = 99; // z2 is an int

Conclusión

Prefiera la inicialización {} sobre las alternativas a menos que tenga una razón sólida para no hacerlo.


Ya hay grandes respuestas sobre las ventajas de usar la inicialización de listas, sin embargo, mi regla de oro personal NO es usar llaves cuando sea posible, sino que depende de su significado conceptual:

  • Si el objeto que estoy creando contiene conceptualmente los valores que estoy pasando en el constructor (por ejemplo, contenedores, estructuras POD, atómicas, punteros inteligentes, etc.), entonces estoy usando las llaves.
  • Si el constructor se parece a una llamada de función normal (realiza algunas operaciones más o menos complejas que están parametrizadas por los argumentos), entonces estoy usando la sintaxis de llamada de función normal.
  • Para la inicialización por defecto siempre uso llaves.
    Por un lado, de esa manera siempre estoy seguro de que el objeto se inicializa independientemente de si, por ejemplo, es una clase "real" con un constructor predeterminado al que se llamaría de todos modos o un tipo incorporado / POD. En segundo lugar, en la mayoría de los casos es consistente con la primera regla, ya que un objeto inicializado predeterminado a menudo representa un objeto "vacío".

En mi experiencia, este conjunto de reglas se puede aplicar de forma mucho más coherente que el uso de llaves por defecto, pero tener que recordar explícitamente todas las excepciones cuando no se pueden usar o tienen un significado diferente al de la sintaxis de llamada de función "normal" entre paréntesis (llama a una sobrecarga diferente).

Por ejemplo, se adapta muy bien a los tipos de biblioteca estándar como std::vector :

vector<int> a{10,20};   //Curly braces -> fills the vector with the arguments

vector<int> b(10,20);   //Parentesis -> uses arguments to parameterize some functionality,                          
vector<int> c(it1,it2); //like filling the vector with 10 integers or copying a range.

vector<int> d{};      //empty braces -> default constructs vector, which is equivalent
                      //to a vector that is filled with zero elements

Existen MUCHAS razones para usar la inicialización de llaves, pero debe tener en cuenta que el constructor initializer_list<> es preferido a los otros constructores , con la excepción del constructor predeterminado. Esto conduce a problemas con los constructores y las plantillas donde el constructor de tipo T puede ser una lista de inicializadores o un ctor antiguo.

struct Foo {
    Foo() {}

    Foo(std::initializer_list<Foo>) {
        std::cout << "initializer list" << std::endl;
    }

    Foo(const Foo&) {
        std::cout << "copy ctor" << std::endl;
    }
};

int main() {
    Foo a;
    Foo b(a); // copy ctor
    Foo c{a}; // copy ctor (init. list element) + initializer list!!!
}

Suponiendo que no encuentre estas clases, hay pocas razones para no usar la lista de intializer.


Principiante

Introducción, sin experiencia previa en programación.

  • C ++ Primer * (Stanley Lippman, Josée Lajoie y Barbara E. Moo) ( actualizado para C ++ 11 ) Próximamente en 1k páginas, esta es una introducción muy completa a C ++ que cubre casi todo en el idioma en un formato muy accesible. y en gran detalle. La quinta edición (publicada el 16 de agosto de 2012) cubre C ++ 11. [Review]

  • Programación: principios y práctica utilizando C ++ (Bjarne Stroustrup, 2ª edición, 25 de mayo de 2014) ( actualizado para C ++ 11 / C ++ 14 ) Una introducción a la programación utilizando C ++ por el creador del lenguaje. Una buena lectura, que no asume experiencia previa en programación, pero no es solo para principiantes.

* No debe confundirse con C ++ Primer Plus (Stephen Prata), con una review significativamente menos favorable.

Introductorio, con experiencia previa en programación.

  • Un recorrido por C ++ (Bjarne Stroustrup) ( 2ª edición para C ++ 17 ) El "recorrido" es un tutorial rápido (alrededor de 180 páginas y 14 capítulos) de todo el C ++ estándar (lenguaje y biblioteca estándar, y uso de C ++ 11 ) en un nivel moderadamente alto para las personas que ya conocen C ++ o al menos son programadores experimentados. Este libro es una versión extendida del material que constituye los Capítulos 2-5 de The C ++ Programming Language, 4ta edición.

  • C ++ acelerado (Andrew Koenig y Barbara Moo, 1ª edición, 24 de agosto de 2000) Básicamente cubre el mismo terreno que el Primer C ++ , pero lo hace en una cuarta parte de su espacio. Esto se debe en gran parte a que no intenta ser una introducción a la programación , sino una introducción a C ++ para personas que previamente han programado en otro idioma. Tiene una curva de aprendizaje más pronunciada, pero, para aquellos que pueden lidiar con esto, es una introducción muy compacta al lenguaje. (Históricamente, abrió nuevos caminos al ser el primer libro para principiantes en utilizar un enfoque moderno para enseñar el idioma). A pesar de esto, el C ++ que enseña es puramente C ++ 98. [Review]

Mejores prácticas

  • C ++ efectivo (Scott Meyers, 3ª edición, 22 de mayo de 2005) Esto se escribió con el objetivo de ser el mejor libro que los programadores de C ++ deberían leer, y tuvieron éxito. Las ediciones anteriores estaban dirigidas a programadores de C, la tercera edición cambia esto y se dirige a programadores de lenguajes como Java. Presenta ~ 50 reglas de oro fáciles de recordar junto con su lógica en un estilo muy accesible (y agradable). Para C ++ 11 y C ++ 14, los ejemplos y algunos problemas están desactualizados y se debería preferir C ++ moderno y efectivo. [Review]

  • Effective Modern C ++ (Scott Meyers) Esta es básicamente la nueva versión de Effective C ++ , dirigida a los programadores de C ++ que hacen la transición de C ++ 03 a C ++ 11 y C ++ 14.

  • STL efectivo (Scott Meyers) Esto apunta a hacer lo mismo con la parte de la biblioteca estándar que proviene del STL que hizo C ++ efectivo con el lenguaje en su conjunto: presenta reglas generales junto con su justificación. [Review]

Intermedio

  • C ++ más efectivo (Scott Meyers) Incluso más reglas de oro que C ++ efectivo . No es tan importante como los del primer libro, pero es bueno saberlo.

  • Excepcional C ++ (Herb Sutter) Presentado como un conjunto de rompecabezas, tiene una de las mejores y exhaustivas discusiones sobre la gestión adecuada de los recursos y la seguridad excepcional en C ++ a través de la Adquisición de Recursos es la Inicialización (RAII), además de la cobertura en profundidad de una variedad de otros temas, incluido el lenguaje pimpl, búsqueda de nombres, buen diseño de clase y el modelo de memoria C ++. [Review]

  • Más Excepcional C ++ (Herb Sutter) Cubre temas de seguridad de excepciones adicionales no cubiertos en Excepcional C ++ , además de la discusión de la programación efectiva orientada a objetos en C ++ y el uso correcto de la STL. [Review]

  • Estilo excepcional de C ++ (Herb Sutter) Analiza la programación genérica, la optimización y la administración de recursos; Este libro también tiene una excelente exposición de cómo escribir código modular en C ++ mediante el uso de funciones que no son miembros y el principio de responsabilidad única. [Review]

  • Normas de codificación de C ++ (Herb Sutter y Andrei Alexandrescu) "Normas de codificación" aquí no significa "¿cuántos espacios debo sangrar con mi código?" Este libro contiene 101 prácticas recomendadas, modismos y dificultades comunes que pueden ayudarlo a escribir correctamente. Código de C ++ comprensible y eficiente. [Review]

  • Plantillas de C ++: la guía completa (David Vandevoorde y Nicolai M. Josuttis) Este es el libro sobre plantillas como existía antes de C ++ 11. Cubre todo, desde lo más básico hasta algunos de los metaprogramas de plantillas más avanzados, y explica cada detalle de cómo funcionan las plantillas (tanto conceptualmente como en la forma en que se implementan) y analiza muchas dificultades comunes. Tiene excelentes resúmenes de la Regla de definición única (ODR) y la resolución de sobrecarga en los apéndices. Ya se ha publicado una segunda edición que abarca C ++ 11, C ++ 14 y C ++ 17. [Review]

Avanzado

  • Modern C ++ Design (Andrei Alexandrescu) Un libro innovador sobre técnicas avanzadas de programación genérica. Introduce el diseño basado en políticas, las listas de tipos y los lenguajes de programación genéricos fundamentales y luego explica la cantidad de patrones de diseño útiles (incluidos los asignadores de objetos pequeños, los funtores, las fábricas, los visitantes y los múltiples métodos) que se pueden implementar de manera eficiente, modular y limpia utilizando la programación genérica . [Review]

  • Plantilla de C ++ Metaprogramación (David Abrahams y Aleksey Gurtovoy)

  • C ++ Concurrencia en Acción (Anthony Williams) Un libro que cubre el soporte de concurrencia de C ++ 11, incluida la biblioteca de hilos, la biblioteca atómica, el modelo de memoria de C ++, bloqueos y exclusión mutua, así como problemas de diseño y depuración de aplicaciones de multiproceso.

  • Metaprogramación avanzada en C ++ (Davide Di Gennaro) Un manual de técnicas TMP pre-C ++ 11, centrado más en la práctica que en la teoría. Hay un montón de fragmentos en este libro, algunos de los cuales se vuelven obsoletos por los rasgos de tipo, pero las técnicas, sin embargo, son útiles para conocer. Si puede soportar el formato / edición peculiar, es más fácil de leer que Alexandrescu y, posiblemente, más gratificante. Para los desarrolladores más experimentados, existe una buena posibilidad de que pueda encontrar algo sobre un rincón oscuro de C ++ (una peculiaridad) que generalmente solo se obtiene a través de una amplia experiencia.

Estilo de referencia - Todos los niveles

  • El lenguaje de programación de C ++ (Bjarne Stroustrup) ( actualizado para C ++ 11 ) La introducción clásica a C ++ por su creador. Escrito para coincidir con el clásico K&R, esto se parece mucho a eso y cubre casi todo, desde el lenguaje central hasta la biblioteca estándar, hasta paradigmas de programación y la filosofía del lenguaje. [Review] Nota: Todas las versiones del estándar C ++ se rastrean en esta pregunta: ¿Dónde encuentro el estándar actual de C ++ ?

  • Tutorial y referencia de la biblioteca estándar de C ++ (Nicolai Josuttis) ( actualizado para C ++ 11 ) La introducción y referencia para la biblioteca estándar de C ++. La segunda edición (publicada el 9 de abril de 2012) cubre C ++ 11. [Review]

  • Los flujos y entornos locales de C ++ IO (Angelika Langer y Klaus Kreft) Hay muy poco que decir sobre este libro, excepto que, si quieres saber algo sobre flujos y lugares, este es el lugar para encontrar respuestas definitivas. [Review]

C ++ 11/14/17 /… Referencias:

  • El estándar C ++ 11/14/17 (INCITS / ISO / IEC 14882: 2011/2014/2017) Este, por supuesto, es el árbitro final de todo lo que es o no es C ++. Tenga en cuenta, sin embargo, que está pensado únicamente como una referencia para usuarios experimentados que estén dispuestos a dedicar un tiempo y esfuerzo considerables a su comprensión. El estándar C ++ 17 se publica en formato electrónico para 198 francos suizos.

  • El estándar C ++ 17 está disponible, pero aparentemente no es económico, 17 cuesta 198 francos suizos (alrededor de $ 200 dólares estadounidenses). Para la mayoría de las personas, el borrador final antes de la estandarización es más que adecuado (y gratuito). Muchos preferirán un borrador aún más reciente , que documente las nuevas características que probablemente se incluirán en C ++ 20.

  • Descripción general del Nuevo C ++ (C ++ 11/14) (solo PDF) (Scott Meyers) ( actualizado para C ++ 1y / C ++ 14 ) Estos son los materiales de presentación (diapositivas y algunas notas de clase) de un Curso de capacitación diurno ofrecido por Scott Meyers, quien es un autor muy respetado en C ++. A pesar de que la lista de artículos es corta, la calidad es alta.

  • Las Directrices básicas de C ++ (C ++ 11/14/17 /…) (editadas por Bjarne Stroustrup y Herb Sutter) son un documento en línea en evolución que consiste en un conjunto de directrices para el uso del C ++ moderno. Las directrices se centran en problemas de nivel relativamente alto, como las interfaces, la gestión de recursos, la gestión de la memoria y la concurrencia que afectan la arquitectura de la aplicación y el diseño de la biblioteca. El proyecto fue anunciado en CppCon'15 por Bjarne Stroustrup y otros y agradece las contribuciones de la comunidad. La mayoría de las directrices se complementan con una justificación y ejemplos, así como con discusiones sobre el posible soporte de herramientas. Muchas reglas están diseñadas específicamente para que las herramientas de análisis estático puedan verificarlas automáticamente.

  • La Super-FAQ de C ++ (Marshall Cline, Bjarne Stroustrup y otros) es un esfuerzo de la Standard C ++ Foundation para unificar las preguntas frecuentes de C ++ previamente mantenidas individualmente por Marshall Cline y Bjarne Stroustrup y también incorporando nuevas contribuciones. La mayoría de los elementos abordan problemas en un nivel intermedio y, a menudo, se escriben con un tono humorístico. No todos los elementos pueden estar completamente actualizados con la última edición del estándar C ++ todavía.

  • cppreference.com (C ++ 03/11/14/17 /…) (iniciado por Nate Kohl) es una wiki que resume las funciones básicas del lenguaje central y tiene una extensa documentación de la biblioteca estándar de C ++. La documentación es muy precisa pero es más fácil de leer que el documento estándar oficial y proporciona una mejor navegación debido a su naturaleza wiki. El proyecto documenta todas las versiones del estándar C ++ y el sitio permite filtrar la pantalla para una versión específica. El proyecto fue presentado por Nate Kohl en CppCon'14 .

Clásicos / mayores

Nota: Es posible que parte de la información contenida en estos libros no esté actualizada o ya no se considere la mejor práctica.

  • El diseño y la evolución de C ++ (Bjarne Stroustrup) Si desea saber por qué el lenguaje es como es, este libro es donde encontrará respuestas. Esto cubre todo antes de la estandarización de C ++.

  • Reflexiones sobre C ++ - (Andrew Koenig y Barbara Moo) [Review]

  • Estilos y expresiones de programación avanzados en C ++ (James Coplien) Un antecesor del movimiento de patrones, describe muchas “expresiones idiomáticas” específicas de C ++. Sin duda, es un libro muy bueno y aún puede valer la pena leerlo si puede ahorrar tiempo, pero es bastante antiguo y no está actualizado con el C ++ actual.

  • Diseño de software C ++ a gran escala (John Lakos) Lakos explica técnicas para gestionar proyectos de software C ++ muy grandes. Ciertamente, una buena lectura, si solo estuviera al día. Fue escrito mucho antes de C ++ 98 y falla en muchas características (por ejemplo, espacios de nombres) importantes para proyectos a gran escala. Si necesita trabajar en un gran proyecto de software de C ++, es posible que desee leerlo, aunque debe llevar consigo más de un grano de sal. El primer volumen de una nueva edición se espera para 2018 .

  • Dentro del Modelo de objetos de C ++ (Stanley Lippman) Si desea saber cómo se implementan comúnmente las funciones de los miembros virtuales y cómo los objetos base se presentan comúnmente en la memoria en un escenario de herencia múltiple, y cómo todo esto afecta el rendimiento, aquí es donde lo hará. encontrar discusiones exhaustivas de tales temas.

  • El manual de referencia de C ++ anotado (Bjarne Stroustrup, Margaret A. Ellis) Este libro está bastante anticuado en el hecho de que explora la versión de C ++ 2.0 de 1989: aún no se presentaron las plantillas, las excepciones, los espacios de nombres y los nuevos modelos. Sin embargo, este libro repasa todo el estándar de C ++ de la época y explica las razones, las posibles implementaciones y las características del lenguaje. Este no es un libro para aprender los principios y patrones de programación en C ++, sino para comprender todos los aspectos del lenguaje C ++.

  • Pensando en C ++ (Bruce Eckel, 2ª Edición, 2000). Dos volúmenes; Es un juego de estilo tutorial gratuito de introducción a nivel de libros. Descargas: vol 1 , vol 2 . Desafortunadamente, están marcados por una serie de errores triviales (por ejemplo, mantener que los temporales son const automáticamente), sin lista de erratas oficial. Una lista parcial de erratas de terceros está disponible en ( http://www.computersciencelab.com/Eckel.htm ), pero aparentemente no se mantiene.

  • C ++ científico y de ingeniería: Introducción a las técnicas y ejemplos avanzados (John Barton y Lee Nackman) Es un libro completo y muy detallado que trató de explicar y hacer uso de todas las funciones disponibles en C ++, en el contexto de los métodos numéricos. Introdujo en ese momento varias técnicas nuevas, como el Patrón de plantilla curioso recurrente (CRTP, también llamado truco de Barton-Nackman). Fue pionero en varias técnicas como el análisis dimensional y la diferenciación automática. Viene con un montón de código compilable y útil, que va desde un analizador de expresiones a un envoltorio Lapack. El código todavía está disponible aquí: http://www.informit.com/store/scientific-and-engineering-c-plus-plus-an-introduction-9780201533934 . Desafortunadamente, los libros se han vuelto un tanto anticuados en el estilo y las características de C ++, sin embargo, fue un increíble tour de force en ese momento (1994, pre-STL). Los capítulos sobre la herencia dinámica son un poco complicados de entender y no son muy útiles. Una versión actualizada de este libro clásico que incluye semántica de movimientos y las lecciones aprendidas de STL sería muy agradable.





c++ c++11 syntax initialization list-initialization