Espacios de nombres
Variantes
Acciones

Tipos

De cppreference.com
< cpp‎ | language

Los objetos, referencias, funciones (incluyendo funciones especializadas de plantilla), y expresiones tienen una propiedad denominada “tipo”, que restringe las operaciones que se pueden realizar con esas entidades, y además le provee de un significado semántico a una secuencia genérica de bits.

Contenido

[editar] Clasificación de tipos

El sistemas de tipos en C++ consiste en los siguientes tipos:

  • tipo lógico, bool;
  • tipos de carácter:
  • tipos simples de carácter (char, signed char, unsigned char);
  • tipos extendidos de carácter (char16_t, char32_t, wchar_t);
  • tipos enteros con signo (short int, int, long int, long long int);
  • tipos enteros sin signo (unsigned short int, unsigned int, unsigned long int, unsigned long long int);
  • tipos referencia lvalue a objeto;
  • tipos referencia lvalue a función;
  • tipos referencia rvalue a objeto;
  • tipos referencia rvalue a función;

Para cada tipo, que no sea una referencia o función, el sistema de tipos admite además tres versiones cualificadas de tipo: (const, volatile y const volatile).

Los tipos se agrupan en varias categorías según sus propiedades:

[editar] Denominación de tipos

Un nombre puede ser declarado para referirse a un tipo que significa:

A menudo, en programas de C++, se necesita usar tipos que no tienen nombre; la sintaxis para esto se conoce como id de tipo. La sintaxis del id de tipo que nombra al tipo T es exactamente la sintaxis de una declaración de una variable o función de tipo T, omitiendo el identificador, excepto que la secuencia de declaración de especificaciones de la gramática de declaración está restringido a una secuencia específica de tipo, y que los nuevos tipos pueden definirse solo si el id de tipo aparece en el lado derecho de una declaración de un alias que no sea de plantilla.

int* p;               // declaración de puntero a entero
static_cast<int*>(p); // el id de tipo es "int*"
 
int a[3];   // declaración de un vector de 3 enteros
new int[3]; // id de tipo es "int[3]" (denominado new-type-id)
 
int (*(*x[2])())[3];      // declaración de un vector de 2 punteros a función
                          // devuelve un puntero a un vector de 3 enteros
new (int (*(*[2])())[3]); // id de tipo es "int (*(*[2])())[3]"
 
void f(int);                    // declaración de una función con un entero de parámetro 
                                //y que no devuelve un valor (void).
std::function<void(int)> x = f; // el tipo del parámetro de la plantilla (template) es 
                                //id de tipo "void(int)"
std::function<auto(int) -> void> y = f; // igual
 
std::vector<int> v;       // declaración de un vector de enteros
sizeof(std::vector<int>); // id de tipo es "std::vector<int>"
 
struct { int x; } b;         // se crea nuevo tipo y se declara un objeto b de ese tipo
sizeof(struct{ int x; });    // error: no se puede definir nuevos tipos en expresión sizeof
using t = struct { int x; }; // se crea nuevo tipo y se declara t como un alias de ese tipo
 
sizeof(static int); // error: los especificadores de tipo de almacenamiento no son parte 
                    //de la secuencia específica de tipo 
std::function<inline void(int)> f; // error: tampoco son específica de función

La parte de “declaración” de la gramática donde no se especifica el nombre se conoce como “declaración abstracta”.

Id de tipo se puede utilizar en la siguientes situaciones:


El “id de tipo” se puede usar con algunos modificadores en los siguientes casos:

  • en la lista de parámetros de una función (cuando se omite el nombre del parámetro), id de tipo usa una secuencia de especificaciones de declaración en vez de una secuencia de especificaciones de tipo (en particular, algunos especificadores de almacenamiento se permiten);
  • en el nombre de una función de conversión definida por usuario, la declaración abstracta no puede incluir operadores de matriz o función.

[editar] Especificador de tipo

Los especificadores de tipo se pueden usar para referirse a un nombre de clase(class, struct o union) o nombre de enumerado declarado previamente, incluso si el nombre estaba oculto por una declaración sin tipo.

Vea especificador de tipo para más información.

[editar] Tipos estáticos

El tipo de una expresión se denomina como “tipo estático” si es el resultado del análisis en tiempo de compilación del programa. El tipo estático no cambia durante la ejecución del programa.

[editar] Tipos dinámicos

Si alguna expresión glvalue está referida a un objeto polimórfico, el tipo de su objeto derivado se conoce como tipo dinámico.

struct B { virtual ~B() {} }; // tipo polimórfico 
struct D: B {}; // tipo polimórfico
D d; // objeto derivado
B* ptr = &d;
// el tipo estático de (*ptr) es B
// el tipo dinámico de (*ptr) es D

Para las expresiones prvalue, el tipo dinámico siempre es el mismo que el estático.

[editar] Tipos incompletos

Los siguientes son “tipos incompletos”:

En cualquiera de la siguientes situaciones se requiere que la clase T sea completa:

(En general, cuando se debe conocer el tamaño y formato de T).

Si alguna de estas situaciones se da en una unidad de traducción, la definición del tipo debe aparecer en la misma. En otro caso, no es obligatorio.

[editar] Ver también