Saltar a contenido

Última actualización:2026-10-12

Deducción de tipos con decltype en C++

Sobre el autor:

Cuenta pública personal de WeChat:

wechat

1. Uso básico

La sintaxis de decltype es:

decltype (expression)
Los paréntesis aquí son imprescindibles; la función de decltype es “consultar el tipo de una expresión”, de modo que el efecto de la instrucción anterior es devolver el tipo de la expresión expression. Ten en cuenta que decltype únicamente “consulta” el tipo de la expresión y no la “evalúa”.

1.1 Deducir el tipo de una expresión

int i = 4;
decltype(i) a; //推导结果为int。a的类型为int。

1.2 Combinado con using/typedef, para definir tipos.

using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
vector<int >vec;
typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin; i != vec.end(); i++)
{
//...
}
Igual que auto, esto también mejora la legibilidad del código.

1.3 Reutilizar tipos anónimos

En C++ a veces nos encontramos con algunos tipos anónimos, como:

struct 
{
    int d ;
    double b;
}anon_s;
Y gracias a decltype podemos volver a utilizar esa estructura anónima:

decltype(anon_s) as ;//定义了一个上面匿名的结构体

1.4 En programación genérica, combinado con auto, para rastrear el tipo de retorno de una función

Este es también el mayor uso de decltype.

template <typename T>
auto multiply(T x, T y)->decltype(x*y)
{
    return x*y;
}
Para el código completo, consulta: decltype.cpp

2. Reglas de deducción

Para decltype(e), el resultado de la deducción está sujeto a las condiciones siguientes:

Si e es una expresión de identificador sin paréntesis o una expresión de acceso a un miembro de clase, entonces decltype(e) es el tipo de la entidad nombrada por e. Además, si e es una función sobrecargada, se produce un error de compilación. En caso contrario , suponiendo que el tipo de e sea T, si e es un valor expirante, entonces decltype(e) es T&& En caso contrario, suponiendo que el tipo de e sea T, si e es un lvalue, entonces decltype(e) es T&. En caso contrario, suponiendo que el tipo de e sea T, decltype(e) es T.

Un identificador se refiere a los símbolos definidos por el propio programador, excluyendo las palabras clave, los literales y demás símbolos que el compilador necesita usar; la expresión correspondiente a un único identificador es una expresión de identificador. Por ejemplo:

int arr[4]
```entonces arr es una expresión de identificador, mientras que arr[3]+0 no lo es.

Veamos algunos ejemplos:

```c++
int i = 4;
int arr[5] = { 0 };
int *ptr = arr;
struct S{ double d; }s ;
void Overloaded(int);
void Overloaded(char);//重载的函数
int && RvalRef();
const bool Func(int);

//规则一:推导为其类型
decltype (arr) var1; //int[] 标记符表达式

decltype (ptr) var2;//int *  标记符表达式

decltype(s.d) var3;//doubel 成员访问表达式

//decltype(Overloaded) var4;//重载函数。编译错误。

//规则二:将亡值。推导为类型的右值引用。

decltype (RvalRef()) var5 = 1;

//规则三:左值,推导为类型的引用。

decltype ((i))var6 = i;     //int&

decltype (true ? i : i) var7 = i; //int&  条件表达式返回左值。

decltype (++i) var8 = i; //int&  ++i返回i的左值。

decltype(arr[5]) var9 = i;//int&. []操作返回左值

decltype(*ptr)var10 = i;//int& *操作返回左值

decltype("hello")var11 = "hello"; //const char(&)[9]  字符串字面常量为左值,且为const左值。


//规则四:以上都不是,则推导为本类型

decltype(1) var12;//const int

decltype(Func(1)) var13=true;//const bool

decltype(i++) var14 = i;//int i++返回右值
Referencia de estudio: https://www.cnblogs.com/QG-whz/p/4952980.html

Temas relacionados

Comentarios