Есть такой пример:
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. подсказка как исправить ошибку не нужна...
Ну давайте подумаем. constexpr
- это что-то, известное во время компиляции.
void
foo(const size_t n)
{
constexpr size_t k = param(n); //error
//...
}
Как тут может быть k
известно во время компиляции, если оно зависит от n
, которое известно во время выполнения программы?
Update
Попробую своими словами :), не знаю, насколько они стыкуются с буквой стандарта - возможно, в каком-то пункте и не 100% точно.
constexpr
для переменной означает, что она обязана быть определена во время компиляции.
constexpr
для функции означает, что она может быть вычислена компилятором во время компиляции, т.е. что ее результат может быть присвоен
constexpr
-переменной (очевидно, что если ее аргументы - тоже constexpr
).
Очевидно также, что если все вызовы такой функции выполнены во время компиляции - то ее просто незачем компилировать и превращать в код. Если не все - то она будет скомпилирована, как обычная функция, так сказать, с игнорированием описания constexpr
.
Это дополнение внесло ясность?
У нас есть 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 варианта выхода из ситуации:
constexpr
.Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Как убрать предупреждение о неинициализированном массиве в следующем коде, ведь все элементы инициализированы?
Интересует возможность использования в Visual Studio (2017) условных точек останова (conditional breakpoint) с проверкой переменной типа std::stringНиже упрощенный...
Не получается удалить выбранную меткуДобавляю метки следующим образом:
вот мой кодпри клике на кнопку он подменяет в data-theme c default на dark