Можем ли мы опустить const на локальные переменные в constexpr?
Например:
constexpr int g() { return 30; }
constexpr int f()
{
// Can we omit const?
const int x = g();
const int y = 10;
return x + y;
}
Существует ли любая точка в объявлять локальные переменные в функции constexpr
с помощью const
?
Не constexpr
функции с const
локальными переменными эквивалентными для тех, у кого нет const
?
Другими словами, constexpr
на функции налагает (подразумевает) const
на ее локальные переменные?
Ответы
Ответ 1
Те же аргументы для объявления переменных как const
в non constexpr
также применяются к функциям constexpr
:
- Объявление переменной
const
документирует тот факт, что она никогда не будет изменена. Это может в некоторых случаях помочь сделать функцию более читаемой.
- Объявление переменной
const
влияет на разрешение перегрузки и может сделать h(x)
разрешить h
по-разному в зависимости от того, является ли x
const
.
Конечно, в противоположном направлении, как уже упоминалось в комментариях:
Даже в constexpr
функции локальные переменные могут быть изменены. Если эти переменные затем изменяются так, чтобы они были const
, попытки их изменения больше не будут приняты.
Ответ 2
В этом конкретном примере локальные переменные были бы лучше объявлены constexpr
, а не const
, потому что они могут вычисляться во время компиляции:
constexpr int g() { return 30; }
constexpr int f()
{
constexpr int x = g();
constexpr int y = 10;
return x + y;
}
Когда f()
вызывается во время выполнения, без constexpr
on x
и y
(с или без const
on x
и y
), вы предоставляете компилятору возможность инициализации x
и y
во время выполнения вместо времени компиляции. С constexpr
на x
и y
компилятор должен вычислять x
и y
во время компиляции, даже когда f()
выполняется во время выполнения.
Однако в другой функции constexpr
не всегда может использоваться. Например, если f()
и g()
взяли параметр:
constexpr int g(int z) { return z+30; }
constexpr int f(int z)
{
const int x = g(z);
constexpr int y = 10;
return x + y;
}
Теперь x
не может быть помечен constexpr
, потому что z
может не быть константой времени компиляции, и в настоящее время нет возможности ее пометить как таковой. Поэтому в этом случае лучше всего сделать отметку x
const
.
Ответ 3
Вы не только можете, но иногда вы должны (то есть, если переменная изменяется), например:
constexpr size_t f(size_t n) {
size_t val = 1;
if (n == 0) val++;
return val;
}
char arr0[f(0)] = {'a', 'x'};
char arr1[f(1)] = {'y'};
отлично в С++ 14.
Ответ 4
В общем, функция не может быть оценена во время компиляции и поэтому не может быть вызвана в постоянном выражении. Указание функции как constexpr указывает, что ее можно использовать в постоянных выражениях, если ее входные аргументы являются константами. Например, это...
constexpr int n = func(7);
... необходимо оценить во время компиляции.
Это значение constexpr перед функциями. В этом случае не следует, что локальным переменным внутри функции не нужно указывать const.