Как сказать static_assert, что аргументы функции constexpr являются постоянными? - PullRequest
9 голосов
/ 20 марта 2012

У меня есть функция constexpr, которая выглядит примерно так:

constexpr int foo(int bar)
{
   static_assert(bar>arbitrary_number, "Use a lower number please");

   return something_const;
}

Тем не менее, компиляция этого с помощью GCC 4.6.3 постоянно говорит мне

ошибка: 'bar' не может появиться вконстантное выражение

Я пробовал что-то вроде

constexpr int foo(constexpr const int bar)
{
   static_assert(bar>arbitrary_number, "Use a lower number please");

   return something_const;
}

, но constexpr не может использоваться для аргументов функции.

Есть ли какой-нибудь простой способ сообщить компилятору, что панельвсегда постоянная времени компиляции?

Ответы [ 3 ]

17 голосов
/ 20 марта 2012

Есть ли какой-нибудь простой способ сообщить компилятору, что bar всегда является постоянной времени компиляции?

Если bar всегда постоянная времени компиляции, тогда вы должны написать свою функцию как:

template<int bar>
constexpr int foo()
{
   static_assert(bar>arbitrary_number, "Use a lower number please");
   return something_const;
}

Потому что, если вы этого не сделаете и вместо этого напишите то, что уже написали, то в этом случае функцию можно будет вызвать с неконстантным аргументом как Что ж; просто если вы передадите неконстантный аргумент, то функция потеряет свою constexpr -ness.

Обратите внимание, что в приведенном выше коде arbitrary_number также должно быть константным выражением, иначе оно не будет компилироваться.

5 голосов
/ 20 марта 2012

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

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

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

0 голосов
/ 20 марта 2012

foo может использоваться следующим образом:

int i;
std::cin >> i;
foo("foo", i);

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

Если аргументы для ваших функций действительно подразумеваются как постоянные выражения, то они должны быть аргументами шаблона, а не аргументами функции.

...