Bienvenidos sean a este post, hoy veremos una tecnica nueva para los iteradores.
Al final del post anterior mencionamos que los iteradores a partir de C++ 20 se empezaron a aplicar con conceptos. Pero que es un concepto? Bueno, antes de entrar en esos detalles hablemos sobre la abstraccion. Siendo esta esencial para la programacion, primero vimos clases como una manera para representar datos y operaciones como una entidad abstracta. Luego vimos a los templates y como pudimos hacer clases aun mas flexibles, permitiendo manejar varios tipos de datos. Tomemos como ejemplo a vector. Este provee una interfaz generica para almacenar y manipular colecciones de objetos.
Hasta aca podemos decir que sin interfaces, la programacion seria muchisimo mas dificil y son la base de la programacion. Los conceptos introducen aun mas flexibilidad para la programacion generica. Ahora es posible establecer restricciones en parametros de template, comprobar si hay restricciones, y descubrir conductas inconsistentes en la compilacion. Repasemos como es una clase generica:
template <typename T>
class Monedero
{
// el cuerpo de la clase usando al tipo generico
};
Esta es la manera mas generica y estandar para definir una clase generica. Con conceptos podemos reemplazar a typename con una descripcion de type que describen mejor a los parametros de template. Supongamos que nuestro monedero necesita trabajar con tipos que se deben agregar juntos. y necesitaremos que sean agregables. Con esto comentado, vamos a aplicar el concepto en la clase anterior:
template <agregable T>
class Monedero
{
// el cuerpo de la clase usando al tipo generico
};
Con este simple cambio ahora nuestro Monedero puede crear instancias que provean tipos que sean agregables. Cuando el tipo no satisface las restricciones, el compilar nos devuelve un error. Vamos a analizar el siguiente caso:
class Libro
{
// no tiene un operator+
// omitimos el cuerpo para simplificar
};
class Dinero
{
friend constexpr bool operator+(const Dinero&, const Dinero&);
// omitimos el cuerpo para simplificar
private:
double valor_;
};
constexpr bool operator+(const Dinero& a, const Dinero& b) {
return Dinero{a.valor_ + b.valor_};
}
Monedero<Dinero> w;
Monedero<Libro> g;
Tomando la clase Monedero que vimos anteriormente, ahora le agregamos dos clases. La primera sera Libro y no tendra una sobrecarga del operador +. La siguiente clase si tendra la sobrecarga del operador + pero la haremos con una funcion «amiga» de nuestra clase. Y en la parte privada tenemos una variable que sera la usaremos. Luego tenemos la definicion de la funcion amiga de la clase Dinero. Para despues crear dos objetos de Monedero. En el primer caso, se creara bien al momento de compilarlo porque al ser agregable y tener la sobrecarga del operador se cumplen las condiciones pero para el segundo caso, fallara porque no tenemos la sobrecarga.
Pero que como establecemos un concepto? Esto es mediante la palabra concept y la siguiente sintaxis:
template <lista-parametros>
concept nombre = expresion-restriccion;
Debajo del template pasamos al concept con su nombre identificador y la expresion encargada de la restriccion (constraint). Esto es asi para poder usar al tipo del template, y podemos referirnos como tipos que describen otros tipos. Como pueden ver los conceptos dependen mucho de las restricciones (constraints). Un constraint es una manera para especificar requerimientos para argumentos de template, y podemos decir que es un conjunto de restricciones. Veamos como es la implementacion del concepto agregable:
template <typename T>
concept agregable = requires (T obj) { obj + obj; }
Observen como de una manera sencilla se define y se pasa la restriccion que se debe cumplir para satisfacerla al momento de la compilacion. Pero tambien existen muchos conceptos estandar ya definidos en la libreria concepts. Pero tambien podemos unir varios conceptos en uno solo, simplemente haciendo que el nuevo soporte a los otros, y para alcanzar esto debemos usar el operador &&.
En resumen, hoy hemos visto a conceptos, que son, para que sirven, como se aplican, como se definen y un par de curiosidades mas. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donatión
It’s for site maintenance, thanks!
$1.50
