Última atualização:2026-10-12
Dedução de tipos com decltype em C++¶
Sobre o autor:¶
Conta oficial do WeChat:

1.Uso básico¶
A sintaxe de decltype é:
Os parênteses aqui são indispensáveis; a função de decltype é "consultar o tipo de uma expressão". Assim, o efeito da instrução acima é retornar o tipo da expressão expression. Note que decltype apenas "consulta" o tipo da expressão, sem "avaliar" a expressão.
1.1 Deduzir o tipo de uma expressão¶
1.2 Usar em conjunto com 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++)
{
//...
}
Assim como o auto, isso também melhora a legibilidade do código.
1.3 Reutilizar tipos anônimos¶
Em C++, às vezes nos deparamos com alguns tipos anônimos, como:
Com a ajuda do decltype, podemos reutilizar essa estrutura anônima:
1.4 Na programação genérica, combinar com auto para rastrear o tipo de retorno de uma função¶
Este é também o maior uso do decltype.
O código completo está em: decltype.cpp
2.Regras de dedução¶
Para decltype(e), o resultado da dedução é influenciado pelas seguintes condições:
Se e for uma expressão identificador sem parênteses ou uma expressão de acesso a membro de classe, então decltype(e) é o tipo da entidade nomeada por e. Além disso, se e for uma função sobrecarregada, ocorrerá um erro de compilação. Caso contrário, supondo que o tipo de e seja T, se e for um xvalue (valor em extinção), decltype(e) será T&&. Caso contrário, supondo que o tipo de e seja T, se e for um lvalue, decltype(e) será T&. Caso contrário, supondo que o tipo de e seja T, decltype(e) será T.
Identificador refere-se aos nomes definidos pelo próprio programador, excluindo as palavras-chave, literais e demais marcas que o compilador precisa usar; a expressão correspondente a um único identificador é uma expressão identificador. Por exemplo:
então arr é uma expressão identificador, mas arr[3]+0 não é.Veja os exemplos a seguir:
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++返回右值
Referência de estudo: https://www.cnblogs.com/QG-whz/p/4952980.html
Tópicos relacionados¶
- Funções virtuais puras e classes abstratas em C++ | C++那些事
- Asserções com assert em C++ | C++那些事
- Bit fields em C++ | C++那些事
- Implementando polimorfismo de C++ em linguagem C | C++那些事
- Constantes e modificadores com const em C++ | C++那些事
- A família completa do const em C++ | C++那些事
- O operador de desreferência * em C++ | C++那些事
- Inicialização e atribuição em C++ | C++那些事
- Formas de retornar múltiplos valores em C++ | C++那些事
- A palavra-chave mutable em C++ | C++那些事