usando vs typedef en C++

Jay Shaw 12 octubre 2023
  1. la palabra clave usar en C++
  2. la palabra clave typedef en C++
  3. Uso de typedef y using en la definición de plantillas
  4. Conclusión
usando vs typedef en C++

Este artículo trata de distinguir entre typedef y using. En la programación funcional de C++, estas palabras clave tienen el mismo propósito y semántica, dejando una línea de diferencia muy estrecha entre ellas.

Este artículo explicará las palabras clave en diferentes contextos para garantizar que el lector comprenda qué hacen estas palabras clave y las diferencias entre typedef y using.

la palabra clave usar en C++

Comprender la palabra clave using en contraste con typedef es importante para aprender las diferencias entre typedef y using.

Se utiliza para traer objetos al alcance actual del programa. Esto significa que puede usarse como una herramienta de acceso para traer especificadores de C++.

Veamos un ejemplo.

#include <iostream>

int main() {
  using std::cout;
  using std::string;

  int a = 56;
  cout << a;
  return 0;
}

Producción :

56

Aquí, la palabra clave using se usa para acceder a especificadores como cout y string desde el espacio de nombres y llevarlos dentro del alcance del programa.

De manera similar, “usar” también se puede usar para acceder a otros especificadores o traer todo el espacio de nombres usando - “usando el espacio de nombres como estándar”. Esto trae todo el espacio de nombres dentro del alcance del programa, y se puede acceder a cada especificador usando std.

Ejemplo de palabra clave usando

El fragmento de código a continuación crea una clase Padre con un método público agregar que tiene dos variables enteras a y b como parámetros. El método sumar imprime la suma de las dos variables.

La clase hijo deriva de la clase Padre en modo protegido, lo que significa que todos los miembros de la clase Padre se heredarán como miembros protegidos.

Dentro de la función main, se crea una instancia del objeto usando la clase Child, y el método add se deriva usando ese objeto.

#include <iostream>
using namespace std;
class Parent {
 public:
  void add(int a, int b) { cout << "Result = " << a + b << endl; }
};
class Child : protected Parent {
 public:
  using Parent::add;
};
int main() {
  Child obj;
  obj.add(15, 30);
  return 0;
}

Producción :

Result = 45

Aquí, la palabra clave using se utiliza para acceder al método add desde la clase Parent a través de su clase Child.

Implementar bucles con la palabra clave using en C++

La sintaxis aquí implementa el bucle for a través de using.

for (using i = int; i{} != 0;) {
  i++;
}

En el caso de bucles basados en rango, “usar” se usa de la siguiente manera:

std::vector<int> v{1, 2, 3};
for (using Foo = int; Foo f : v) {
  (void)f;
}

Declaraciones Switch Case con la palabra clave using en C++

En declaraciones switch case, using se implementa como:

if (using Foo = int; true) {
  (void)Foo{};
}
switch (using Foo = int; 0) {
  case 0:
    (void)Foo{};
}

la palabra clave typedef en C++

La palabra clave typedef tiene la función de nombrar un tipo usando un nombre personalizado. Esto significa que se puede introducir un alias para un tipo de datos existente.

En esta sección se pueden observar las principales diferencias entre typedef y using.

El siguiente programa explica este concepto claramente.

#include <stdio.h>
#include <string.h>

typedef struct Books {
  char title[50];
  char author[50];
  char subject[100];
  int book_id;
} Book;

Se introduce una clase struct Libro, que tiene cuatro variables. Estas cuatro variables se estructuran como un nuevo tipo de datos utilizando typedef, y a este tipo se le da el nombre de Libro.

Dentro de la clase principal, se debe crear un nuevo objeto para acceder al tipo Libro y obtener sus variables (según el requisito).

Se puede observar que las variables individuales se llaman utilizando la sintaxis nombre_objeto.nombre_variable,"entrada". Una vez que estas variables reciben datos, se imprimen usando el mismo método que se usó para llamarlos.

int main() {
  Book book;

  strcpy(book.title, "Typedef vs using");
  strcpy(book.author, "JS");
  strcpy(book.subject, "C Programming");
  book.book_id = 6495407;

  printf("Book title : %s\n", book.title);
  printf("Book author : %s\n", book.author);
  printf("Book subject : %s\n", book.subject);
  printf("Book book_id : %d\n", book.book_id);

  return 0;
}

Producción :

Book title : Typedef vs using
Book author : JS
Book subject : C Programming
Book book_id : 6495407

Bucles utilizando la palabra clave typedef en C++

Durante la iteración del bucle, typedef se define usando la sintaxis for (typedef (tipo de datos)Función; Función{} != 0;).

for (typedef int i; i{} != 0;) {
  i++;
}

Durante una iteración de bucle basada en rango, typedef se usa como:

std::vector<int> v{1, 2, 3};
for (typedef int Foo; Foo f : v)
//   ^^^^^^^^^^^^^^^ init-statement
{
  (void)f;
}

Otro ejemplo de un bucle basado en rango dentro de una matriz 2-D:

for (typedef struct {
       int x;
       int y;
     } P;
     auto [x, y] : {P{1, 1}, {1, 2}, {3, 5}}) {
  (void)x;
  (void)y;
}

Declaraciones Switch Case usando la palabra clave typedef en C++

La palabra clave typedef se usa en declaraciones switch case, como se muestra a continuación.

if (typedef int Foo; true) {
  (void)Foo{};
}

switch (typedef int Foo; 0) {
  case 0:
    (void)Foo{};
}

Uso de typedef y using en la definición de plantillas

Hemos observado diferencias entre typedef y using desde el contexto de la programación funcional. Otra parte importante que debe entenderse es cómo definir plantillas.

En C++, typedefs tenía la función de definir alias para plantillas. Se ha utilizado durante mucho tiempo, pero se observó que la semántica de typedef no va bien con las plantillas.

Para resolver el problema, se ha depreciado typedef y se ha llevado a cabo using.

En los siguientes ejemplos, las diferencias entre typedef y using se analizan en el contexto de la definición de plantillas.

Plantilla de aliasing con typedef en C++

Ejemplo 1:

Aquí, se ha definido que un rectángulo tiene una longitud x y una anchura estática que debe recibir un alias mediante plantillas.

El <size_t N> es una plantilla que almacena la longitud del rectángulo. En contraste, Dimensión es un objeto al que se le dará el alias Rectángulo usando typedef.

Aquí, el código asigna el Rectángulo para que sea un alias de Dimensión<N,1>, lo que significa que el objeto Dimensión tendrá un largo y un ancho. Aquí, el objeto Dimensión tiene una longitud <size_t N> y una anchura de 1.

template <size_t N>
struct Rectangle {
  typedef Dimension<N, 1> type;
};

Esto implica que el programador necesita pasar un parámetro de valor único, size_t N al Rectángulo. El compilador tomará lo pasado como la longitud, mientras que la anchura se establece en 1.

La sintaxis Rectángulo<5>::int pasa el valor entero 5 al objeto Dimensión y será lo mismo que escribir Dimensión<5,1>.

Los ejemplos anteriores ya no se usan en la versión reciente de C++ ya que se deprecia typedef. Tomar el uso de using para dar un alias a las plantillas es más simple que el ejemplo anterior.

Ejemplo 2:

La clase de plantilla Coincidencia se define en el fragmento de código a continuación. A esta clase Match se le asigna una plantilla de alias MatchBox.

La clase Match también se puede sustituir en el futuro.

template <typename U>
struct Match {};

template <typename U>
struct MatchBox {
  typedef Match<U> type;
};

MatchBox<int>::type variable;

template <typename V>
struct bar {
  typename MatchBox<V>::type_var_member;
}

Si se requiere abstracción de tipo, pero también se debe conservar el parámetro de plantilla para que pueda proporcionarse en el futuro, este es el tipo de código que se debe escribir.

Aliasing de plantillas con la palabra clave using en C++

Ejemplo 1:

Esta sección dibuja las diferencias entre typedef y using en el contexto de las plantillas. Aquí, la plantilla <size_t N> es la misma que la utilizada en el ejemplo 1 typedef, que almacena la longitud del rectángulo.

En lugar de utilizar estructura, el alias Rectángulo se asigna al objeto Dimensión a través de la palabra clave usando. Esto se hace de la misma manera que se asigna un operador.

El alias Rectángulo después de la asignación del alias tiene N y 1 como largo y ancho, respectivamente.

template <size_t N>
using Rectangle = Dimension<N, 1>;

Se puede observar que using proporciona una versión más refinada de aliasing, que es más fácil de escribir e implementar. La legibilidad de la sintaxis utilizada aquí parece mejorada porque ahora se parece más a la asignación convencional de variables y operadores.

Ejemplo 2:

Este ejemplo mantiene abierto el parámetro de plantilla para que sea posible especificarlo. En el ejemplo de typedef, este proceso requería múltiples líneas de códigos. Pero la sintaxis de uso reduce el código y la complejidad.

template <typename U>
using MatchBox = Match < U

                             MatchBox<int>
                                 variable;
template <typename V>
struct bar {
  MatchBox<V> _var_member;
}

Usar la palabra clave using para definir un alias para plantillas es mucho más fácil que typedef porque el proceso es similar a copiar la asignación de variables.

Conclusión

Este artículo cubre las diferencias entre las palabras clave typedef y using en C++. El lector comprenderá las diferencias básicas y la implementación de estas palabras clave en diferentes contextos de programación.

Se espera que este artículo le haya ayudado en su viaje de aprendizaje.