Подтвердить что ты не робот

Можем ли мы опустить 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 на ее локальные переменные?

4b9b3361

Ответ 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.