Adrián Arroyo Calle

if-init



// ANTES

Device dev = get_device();

if(dev.isOk()){

dev.hacerCosas();

}



// AHORA

if(Device dev = get_device(); dev.isOk()){

dev.hacerCosas();

}



Declaraciones de descomposición



// FUNCIÓN QUE DEVUELVE TUPLA

std::tuple<int, std::string> funcion();



// C++14

auto tup = funcion();

int i = std::get<0>(tup);

std::string s = std::get<1>(tup);



// C++17

auto [i,s] = funcion();







std::map m = ...;

for(auto && [key, value] : m){



}



Deduction Guides



// ANTES

auto p = std::pair<int,std::string>(42,"Adrianistan");



// AHORA

auto p = std::pair(42,"Adrianistan");





template<typename T>

struct Thingy

{

T t;

};



// Observa

Thingy(const char *) -> Thingy<std::string>;



Thingy thing{"A String"}; // thing.t es de tipo std::string



template auto



// ANTES

template <typename T, T v>

struct integral_constant

{

static constexpr T value = v;

};

integral_constant<int, 2048>::value

integral_constant<char, 'a'>::value



// AHORA

template <auto v>

struct integral_constant

{

static constexpr auto value = v;

};

integral_constant<2048>::value

integral_constant<'a'>::value



Fold expressions



template <typename... Args>

auto sum(Args&&... args) {

return (args + ... + 0);

}



Namespaces anidados



// ANTES



namespace A{

namespace B {

bool check();

}

}



// AHORA



namespace A::B {

bool check();

}



Algunos [[atributos]] nuevos

[[maybe_unused]]



int x = 5;

[[maybe_unused]] bool azar = true;

x = x + 10



[[fallthrough]]



switch (device.status())

{

case sleep:

device.wake();

[[fallthrough]];

case ready:

device.run();

break;

case bad:

handle_error();

break;

}



Variables inline



// ANTES

// en una cabecera para que la usasen los demás

extern int x;



// solo en un fichero fuente, para inicializarla

int x = 42;

// AHORA



// en la cabecera

inline int x = 42;





if constexpr



template<class T>

void f (T x)

{

if constexpr(std:: is_integral <T>::value) {

implA(x);

}

else if constexpr(std:: floating_point <T>::value) {

implB(x);

}

else

{

implC(x);

}

}



std::optional



std::optional opt = f();

if(opt)

g(*opt);



// otra opción de uso si queremos proveer de un reemplazo

std::optional opt = f();

std::cout << opt.value_or(0) << std::endl;



std::variant



std::variant<int, double, std::vector> precio; // precio puede ser un int, un double o un std::vector



// comprobar si el valor en un variant es de un determinado tipo

if(std::holds_alternative<double>(precio))

double x = std::get<double>(precio);



std::any



std::any v = ...;

if (v.type() == typeid(int)) {

int i = any_cast<int>(v);

}



std::filesystem



#include <filesystem>

#include <iostream>

namespace fs = std::filesystem;



void main(){

fs::path dir = "/";

dir /= "sandbox";

fs::path p = dir / "foobar.txt";

std::cout << p.filename() << "

";

fs::copy(dir, "/copy", fs::copy_options::recursive);

}



Algoritmos en paralelo



std::sort(std::execution::par, first, last);



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



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:

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++14Ahora 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.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,...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: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.Bastante autoexplicativoSe usa para suprimir la advertencia del compilador de que no estamos usando una determinada variable.Permite usar los switch en cascada sin advertencias del compilador.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.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.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.Descritas como las unions pero bien hechas. Pueden contener variables de los tipos que nosotros indiquemos.Si con std::variant restringimos los posibles tipos de la variable a los indicados, con std::any admitimos cualquier cosa.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.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.Ya hemos visto lo que trae C++17. Ahora veremos que se espera que traiga C++20 en 2020.