Как сказать static_assert, что аргументы функции constexpr являются постоянными?
У меня есть функция constexpr, которая выглядит примерно так:
constexpr int foo(int bar)
{
static_assert(bar>arbitrary_number, "Use a lower number please");
return something_const;
}
Тем не менее, сборка этого с GCC 4.6.3 продолжает говорить мне
ошибка: "бар" не может появляться в константном выражении
Я пробовал что-то вроде
constexpr int foo(constexpr const int bar)
{
static_assert(bar>arbitrary_number, "Use a lower number please");
return something_const;
}
но constexpr не может использоваться для аргументов функции.
Есть ли какой-нибудь простой способ сообщить компилятору, что bar всегда является постоянной времени компиляции?
3 ответа
Есть ли какой-нибудь простой способ сообщить компилятору, что bar всегда является постоянной времени компиляции?
Если bar
всегда константа времени компиляции, тогда вы должны написать свою функцию как:
template<int bar>
constexpr int foo()
{
static_assert(bar>arbitrary_number, "Use a lower number please");
return something_const;
}
Потому что, если вы этого не сделаете, а вместо этого напишите то, что уже написали, то в этом случае функцию также можно вызывать с неконстантным аргументом; просто если вы передадите неконстантный аргумент, функция потеряет свою запутанность.
Обратите внимание, что в приведенном выше коде arbitrary_number
также должно быть константным выражением, иначе оно не будет компилироваться.
constexpr
функции могут быть оценены во время компиляции, это не предписывается стандартом в целом (вы можете заставить функцию быть оцененной во время компиляции, используя ее внутри константного выражения, как инициализация constexpr
переменная с ним).
Кроме того, аргументы constexpr
функции на самом деле не являются постоянными, они могут меняться при каждом вызове (даже если оцениваются во время компиляции)
Обходной путь - использовать нетипичный шаблон для передачи bar
, если это всегда постоянная времени компиляции (что кажется).
foo
может использоваться следующим образом:
int i;
std::cin >> i;
foo("foo", i);
Как вы видете i
не является константным выражением выше, но оно все еще может быть использовано с constexpr
функции. constexpr
функции (и шаблоны функций) - странный зверь, который гарантирует, что, например, foo(p, i)
константное выражение, если p
а также i
также есть, но все еще может использоваться как обычные функции.
Если аргументы ваших функций действительно должны всегда быть константными выражениями, то они должны быть аргументами шаблона, а не аргументами функции.