Novedades de C++17

Después de tres años de trabajo, C++17 ha sido finalmente estandarizado. Esta nueva versión de C++ incorpora y elimina elementos del lenguaje, con el fin de ponerlo al día y convertirlo en un lenguaje moderno y eficaz. El comité ISO de C++ se ha tomado muy en serio su labor, C++11 supuso este cambio de mentalidad, que se ha mantenido en C++14 y ahora en C++17, la última versión de C++.

Repasemos las noveades que incorpora C++17 respecto a C++14

if-init

Ahora podemos incluir una sentencia de inicialización antes de la condición en sentencias if y switch. Esto es particularmente útil si queremos operar con un objeto y desconocemos su validez.

Declaraciones de descomposición

Azúcar sintántico que permite mejorar la legibiliad en ciertas situaciones. Por ejemplo, en el caso de las tuplas, su uso se vuelve trivial.

Esto funciona para multitud de estructuras de datos, como estructuras, arrays, std::array, std::map,…

Deduction Guides

Ahora es menos necesario que nunca indicar los tipos en ciertas expresiones. Por ejemplo, al crear pares y tuplas:

Esto por supuesto también sirve para estructuras y otras construcciones:

template auto

Fold expressions

Imagina que quieres hacer una función suma, que admita un número ilimitado de parámetros. En C++17 no se necesita apenas código.

Namespaces anidados

Bastante autoexplicativo

Algunos [[atributos]] nuevos

[[maybe_unused]]

Se usa para suprimir la advertencia del compilador de que no estamos usando una determinada variable.

[[fallthrough]]

Permite usar los switch en cascada sin advertencias del compilador.

Variables inline

Ahora es posible definir variables en múltiples sitios con el mismo nombre y que compartan una misma instancia. Es recomendable definirlas en un fichero de cabecera para luego reutilizarlas en ficheros fuente.

if constexpr

Ahora es posible introducir condicionales en tiempo de compilación (similar a las macros #IFDEF pero mejor hecho). Estas expresiones con constexpr, lo que quiere decir que son código C++ que se evalúa en tiempo de compilación, no de ejecución.

std::optional

Tomado de la programación funcional, se incorpora el tipo optional, que representa un valor que puede existir o no. Este tipo ya existe en Rust bajo el nombre de Option y en Haskell como Maybe.

std::variant

Descritas como las unions pero bien hechas. Pueden contener variables de los tipos que nosotros indiquemos.

std::any

Si con std::variant restringimos los posibles tipos de la variable a los indicados, con std::any admitimos cualquier cosa.

std::filesystem

Se añade a la librería estándar este namespace con el tipo path y métodos para iterar y operar con directorios. Dile adiós a las funciones POSIX o Win32 equivalentes.

Algoritmos en paralelo

Muchos de los algoritmos de STL ahora pueden ejecutarse en paralelo bajo demanda. Con std::execution::par indicamos que queremos que el algoritmo se ejecute en paralelo.

¿Qué novedades se esperan en C++20?

Ya hemos visto lo que trae C++17. Ahora veremos que se espera que traiga C++20 en 2020.

  • Módulos. Reemplazar el sistema de includes
  • Corrutinas. Mejorar la programación asíncrona
  • Contratos. Mejorar la calidad del código
  • Conceptos. Mejorar la programación genérica
  • Redes. Estandarizar la parte de red en C++ tal y como se ha hecho con std::filesystem
  • Rangos. Nuevos contenedores

Referencias:

 

3 opiniones en “Novedades de C++17”

  1. El artículo está interesante pero has pasado por alto algunos detalles:

    – if-init: También funciona con switch

    – Declaraciones de descomposición: si usas C++14 (e incluso C++11) también podrías haber usado std::tie para explotar la tupla (que si no al final parece que C++14 es casi antediluviano):

    int i;
    std::string s;
    std::tie(i,s) = funcion();

    – Deduction Guides: podías haber explicado que existe std::make_pair y que esta nueva característica pretende acabar con esas funciones de ayuda.

    – Algunos [[atributos]] nuevos: Estaría bien añadir [[nodiscard]] que es bastante importante también

    – if constexpr: Se te olvidó mencionar que, a diferencia de #ifdef, con if constexpr tanto la opción if como la else tienen que ser válidas en tiempo de compilación.

    Y luego hay algunas características bastante interesantes que no has ni mencionado:

    – Los atributos se pueden añadir a espacios de nombres y enumerados

    namespace [[deprecated]] versionVieja{
    void func();
    }
    – Las funciones constexpr se pueden usar para resolver templates:

    constexpr bool func(int n)
    { return n%2==0; }

    template void func2()
    { std::cout << par << '\n'; }

    func2(); // Imprime 1
    func2(); // imprime 0

    – constexpr se puede usar con lambdas:

    constexpr auto lambda = []( int n ) { return n%2==0; };

    Hay más cosillas pero no entran en un comentario 🙂

    1. Muchas gracias por tu comentario. Siempre es un placer leer comenarios así.

      Respecto a los detalles que comentas al principio, estaba al tanto de ellos. De hecho lo de switch si te fijas sí que lo puse, solo que no hice ejemplo, quizá no se ha entendido bien. Sobre desestructurar la tupla con std::tie y el uso de std::make_pair aparece en los artículos que enlazo al final pero al ser varias maneras de hacer lo mismo en C++14 preferí no ponerlo aquí.

      El atributo de [[nodiscard]] lo he ignorado a posta porque puede ser subóptimo y su uso solo es justificable en casos muy concretos.

      Sobre el resto de cosas ahí me has pillado 🙂 No sabía que se hubiese añadido tanto a constexpr y que ahora los namespaces tuvieran atributos.

      Saludos

      1. Gracias por los comentarios y por el blog. No suelen abundar los blogs en español que traten los temas en serio… creo que me pasaré por aquí de vez en cuando.

        Lo de [[nodiscard]] tiene su uso sobretodo en código legado, donde es muy sencillo encontrar punteros retornados sin control alguno. Así con un esfuerzo mínimo pones al compilador a chequear una fuente de fugas de memoria.

        En cuanto al resto, C++14 en comparación con C++17 es un “minor upgrade”. Esperemos que C++20 siga la misma progresión y el lenguaje consiga ponerse al día.

Deja un comentario

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