Функция как константное выражение в вызываемой функции

82
26 октября 2021, 03:50

Есть такой пример:

constexpr int 
param(const size_t n) 
{ return n + 1; }

Аргумент этой функции известен во время выполнения программы, но сама функция может являться константным выражением. Но если ее вызвать в функции с аргументом вызывающей функции, то она не будет явлться константным выражением:

void 
foo(const size_t n)
{
    constexpr size_t k = param(n); //error
    //...
}

Почему функция param, являющимся константным выражением, не считается таковым в вызывающей функции?

P.S. подсказка как исправить ошибку не нужна...

Answer 1

Ну давайте подумаем. constexpr - это что-то, известное во время компиляции.

void 
foo(const size_t n)
{
    constexpr size_t k = param(n); //error
    //...
}

Как тут может быть k известно во время компиляции, если оно зависит от n, которое известно во время выполнения программы?

Update

Попробую своими словами :), не знаю, насколько они стыкуются с буквой стандарта - возможно, в каком-то пункте и не 100% точно.

constexpr для переменной означает, что она обязана быть определена во время компиляции.

constexpr для функции означает, что она может быть вычислена компилятором во время компиляции, т.е. что ее результат может быть присвоен constexpr-переменной (очевидно, что если ее аргументы - тоже constexpr).

Очевидно также, что если все вызовы такой функции выполнены во время компиляции - то ее просто незачем компилировать и превращать в код. Если не все - то она будет скомпилирована, как обычная функция, так сказать, с игнорированием описания constexpr.

Это дополнение внесло ясность?

Answer 2

У нас есть 2 функции.

Первая:

constexpr int param(const size_t n) 
{ 
return n + 1; 
}

Вторая:

void foo(const size_t n)
{
    constexpr size_t k = param(n); //error
    //...
}

Как я понял автора, он желает узнать почему функция param не вычисляется во время компиляции. Для начала поймём, что такой constexpr.

Спецификатор constexpr введен для того, чтобы заставить компилятор на этапе кмпиляции создавать объекты и использовать их как константы времени компиляции.

Смотрим теперь на наши функции, мы вызываем функцию param из функции foo. Зададим вопрос, а как выполнится эта строка constexpr size_t k = param(n); во время компиляции? Никак, потому что мы не можем во время компиляции получить откуда-то параметр n, который требуется в функции foo.

Тут 2 варианта выхода из ситуации:

  1. Изменить код программы, чтобы все функции могли получить нужные параметры на момент компиляции.
  2. Выполнить в рантайме и можно смело удалить constexpr.
READ ALSO
Предупреждение о неинициализированном массиве

Предупреждение о неинициализированном массиве

Как убрать предупреждение о неинициализированном массиве в следующем коде, ведь все элементы инициализированы?

242
VS C++ точки останова с проверкой std::string

VS C++ точки останова с проверкой std::string

Интересует возможность использования в Visual Studio (2017) условных точек останова (conditional breakpoint) с проверкой переменной типа std::stringНиже упрощенный...

155
Удаление метки из кластера Яндекс карты

Удаление метки из кластера Яндекс карты

Не получается удалить выбранную меткуДобавляю метки следующим образом:

183
Темная тема data-Attribute

Темная тема data-Attribute

вот мой кодпри клике на кнопку он подменяет в data-theme c default на dark

195