Спецификатор constexpr. Отличия спецификатора constexpr от const. Примеры
Поиск на других ресурсах:
Содержание
- 1. Спецификатор constexpr. Применение для констант. Пример
- 2. Различия между спецификаторами constexpr и const
- 3. Спецификатор constexpr. Применение для констант. Пример
- 4. Спецификатор constexpr. Применение для возвращающих константу функций. Пример
- 5. Объявления констант constexpr на основе других констант и литералов. Пример
- 6. Пример вызова из constexpr-функции другой constexpr-функции. Цепочка вызовов
- Связанные темы
1. Спецификатор constexpr. Применение для констант. Пример
Специфікатор constexpr може застосовуватись:
- для переменных, которые нужно объявить как константы (для констант);
- для функций.
Общая форма объявления константы со спецификатором constexpr имеет вид
constexpr type ConstantName = value_or_expression;
здесь
- type – тип константы;
- ConstantName – имя константы;
- value_or_expression – значение (литерал) или выражение. В выражении может вызываться функция, отмеченная также как constexpr.
В случае определения для переменных констант, этот спецификатор задает константы так же как и спецификатор const. Однако значения этих констант должны быть определены на этапе компиляции, а не сформированы позже на этапе выполнения. Такие значения, которые определены сразу есть литералами (2.88, «Hello, world!», true).
Общая форма объявления функции со спецификатором constexpr следующая
constexpr return_type FuncName(list_of_parameters) { // ... return const_expr_value; }
здесь
- FuncName – имя функции, возвращающей константу;
- list_of_parameters – список параметров функции;
- const_expr_value – значение, которое может рассчитываться на этапе компиляции. Это может быть результат вызова других constexpr-функций, значение литералов, значение других констант, объявленных со спецификатором constexpr.
⇑
2. Различия между спецификаторами constexpr и const
Между спецификаторами const и constexpr есть следующие отличия:
1. Инициализация переменной const может быть отложена до времени выполнения:
// Здесь sqrt() вычисляется позже, при выполнении программы const double rc1 = sqrt(4.44 + c1); cout << rc1 << endl;
2. Инициализация переменной constexpr не может быть отложена до времени выполнения:
double ce1 = 23.2; constexpr double rce1 = sqrt(2.88); // не работает, поскольку sqrt() вычисляется позже
3. Инициализацию переменной constexpr можно вычислять на основе другой переменной, которая также объявлена как constexpr.
// 1. Инициализация константы constexpr на основе другой константы constexpr constexpr int ce1 = 50; constexpr int ce2 = ce1 * 2 + 100; // ce2 = 200 - работает
также на основе константы, которая объявлена как const
// Попытка инициализации константы constexpr // на основе другой константы, объявленной как const const int c1 = 200; constexpr int ce3 = c1 + 10; // работает, поскольку значение c1 известно на этапе компиляции
4. Константу типа const можно объявлять на основе переменной, а константу типа constexpr нельзя
// Попытка инициализации константы const на основе переменной int v1 = 100; const int c2 = v1 * 3; // работает // Попытка инициализации константы constexpr на основе переменной int v2 = 100; constexpr int ce4 = v2 * 3; // ошибка, чтобы исправить это нужно v2 объявить как constexpr
⇑
3. Спецификатор constexpr. Применение для констант. Пример
// Переменные constexpr допускается инициализировать значением литерала, // поскольку значение литерала сразу определено constexpr double d = true; constexpr double t{ 3.05 }; cout << d << endl; // constexpr float x = exp(2.8); // ошибка const float x = exp(2.8); // работает double f = 0.0; //constexpr double v = f + 2.5; // ошибка, f не есть constexpr // Инициализация переменной const может быть отложена до времени выполнения. // 1. Для констант (const) это все работает double c1 = 23.2; // Здесь sqrt() вычисляется позже, при выполнении программы const double rc1 = sqrt(4.44 + c1); cout << rc1 << endl; // 2. Для констант constexpr это не работает, // то есть инициализация переменной constexpr не может // быть отложена до времени выполнения. // Эта инициализация должна выполняться сразу, // иначе компилятор выдаст ошибку. double ce1 = 23.2; constexpr double rce1 = sqrt(2.88); // не работает, поскольку sqrt() будет вычислено позже constexpr double rce2 = sqrt(ce1); // не работает constexpr double ce2 = 3.8; constexpr double rce3 = sqrt(ce2); // не работает
⇑
4. Спецификатор constexpr. Применение для возвращающих константу функций. Пример
Пример.
#include <iostream> using namespace std; // Для переменных constexpr и const обязательно должен быть инициализатор. // Функция, возвращающая число 10 int GetNumber10() { return 10; } // Другая функция, возвращающая 20 constexpr int GetNumber20() { return 20; } void TestVariable() { // Инициализация переменной const может быть отложена до времени выполнения. // 1. Для констант (const) это все работает double c1 = 23.2; // Здесь sqrt() вычисляется позже, при выполнении программы. const double rc1 = sqrt(4.44 + c1); cout << rc1 << endl; // 2. Для констант constexpr это не работает, // тоесть инициализация constexpr не может // быть отложена до времени выполнения. // Эта инициализация должна выполняться сразу, // иначе компилятор выдаст ошибку. double ce1 = 23.2; //constexpr double rce1 = sqrt(2.88); // не работает, поскольку sqrt() будет вычислено позже //constexpr double rce2 = sqrt(ce1); // не работает constexpr double ce2 = 3.8; //constexpr double rce3 = sqrt(ce2); // не работает } void main() { // Вызов функции // 1. Спецификатор const // Здесь работает, поскольку значение будет получено на этапе выполнения. const int c1 = GetNumber10(); // Здесь также работает, но с предупреждением пометить c2 как constexpr const int c2 = GetNumber20(); cout << c2; // 2. Спецификатор cosnexpr // Не работает, поскольку constexpr-значение должно получаться // на этапе компиляции, а не на этапе выполнения // constexpr int ce1 = GetNumber10(); // Работает, поскольку функция GetNumber20() замечена как таковая, // что ее вызов и возврат значения должны выполняться на этапе компиляции constexpr int ce2 = GetNumber20(); cout << ce2 << endl; }
⇑
5. Объявления констант constexpr на основе других констант и литералов. Пример
// 1. Инициализация константы constexpr на основе другой константы constexpr constexpr int ce1 = 50; constexpr int ce2 = ce1 * 2 + 100; // ce2 = 200 - работает // 2. Попытка инициализации константы constexpr // на основе другой константы, объявленной как const const int c1 = 200; constexpr int ce3 = c1 + 10; // работает, поскольку значение c1 известно на этапе компиляции // 3. Попытка инициализации константы const на основе переменной int v1 = 100; const int c2 = v1 * 3; // работает // 4. Попытка инициализации константы constexpr на основе переменной int v2 = 100; constexpr int ce4 = v2 * 3; // ошибка, чтобы исправить это нужно v2 объявить как constexpr
⇑
6. Пример вызова из constexpr-функции другой constexpr-функции. Цепочка вызовов
#include <iostream> using namespace std; // Функция, которая возвращает число 15 constexpr int GetNumber15() { return 15; } // Другая constexpr-функция, которая возвращает 20. // Эта функция обращается к функции GetNumber15() constexpr int GetNumber20() { return 5 + GetNumber15(); } void main() { // 1. Инициализация константы constexpr на основе другой константы constexpr constexpr int ce1 = 50; constexpr int ce2 = ce1 * 2 + 100; // ce2 = 200 // 2. Попытка инициализации константы constexpr на основе другой константы, объявленной как const const int c1 = 200; constexpr int ce3 = c1 + 10; // работает, поскольку значение c1 известно на этапе компиляции // 3. Попытка инициализации константы const на основе переменной int v1 = 100; const int c2 = v1 * 3; // работает // 4. Попытка инициализации константы constexpr на основе переменной int v2 = 100; //constexpr int ce4 = v2 * 3; // ошибка, чтобы исправить это нужно v2 объявить как constexpr // Вызов функции GetNumber20() для инициализации constexpr-константы с именем d1 constexpr double d1 = GetNumber20(); // 20 - работает cout << d1 << endl; }
⇑
Связанные темы
- Понятие переменной. Объявление переменной. Операция расширения области видимости :: . Выделение памяти для переменной. Константы
- Понятие выражения. Операция присваивания. Преобразование и приведение типов. Инициализация. Унифицированная инициализация
⇑