Последнее обновление:2026-10-12
C++ выведение типов с decltype¶
Об авторе:¶
Личный официальный аккаунт:

1.Основное использование¶
Синтаксис decltype таков:
Скобки здесь обязательны; роль decltype — «запросить тип выражения», поэтому приведённый выше оператор возвращает тип выражения expression. Обратите внимание: decltype лишь «запрашивает» тип выражения и не «вычисляет» само выражение.
1.1 Выведение типа выражения¶
1.2 Использование вместе с using/typedef для определения типов.¶
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++)
{
//...
}
Так же, как и auto, это повышает читаемость кода.
1.3 Повторное использование анонимных типов¶
В C++ мы иногда сталкиваемся с анонимными типами, например:
А с помощью decltype мы можем повторно использовать эту анонимную структуру:
1.4 В сочетании с auto в обобщённом программировании — для отслеживания типа возвращаемого значения функции¶
Это самое главное применение decltype.
Полный код см. в: decltype.cpp
2.Правила определения¶
Для decltype(e) результат определения зависит от следующих условий:
Если e — выражение-идентификатор без скобок или выражение доступа к члену класса, то decltype(e) — это тип сущности, названной через e. Кроме того, если e — перегруженная функция, это приведёт к ошибке компиляции. Иначе, пусть тип e — T: если e — xvalue (будущее значение), то decltype(e) будет T&&. Иначе, пусть тип e — T: если e — lvalue (левостороннее значение), то decltype(e) будет T&. Иначе, пусть тип e — T: тогда decltype(e) будет T.
Идентификатор — это определённый программистом токен, за исключением ключевых слов, литералов и других токенов, которые нужны компилятору; выражение, соответствующее одиночному идентификатору, называется выражением-идентификатором. Например:
тогда arr — выражение-идентификатор, а arr[3]+0 — нет.Примеры:
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++返回右值
Учебный материал: https://www.cnblogs.com/QG-whz/p/4952980.html
Похожие темы¶
- C++ чисто виртуальные функции и абстрактные классы | C++那些事
- C++ утверждения assert | C++那些事
- C++ битовые поля | C++那些事
- Реализация полиморфизма C++ на языке C | C++那些事
- C++ константы const и его модификация | C++那些事
- C++ всё семейство const | C++那些事
- C++ оператор разыменования * | C++那些事
- C++ инициализация и присваивание | C++那些事
- C++ возврат нескольких значений | C++那些事
- C++ ключевое слово mutable | C++那些事