Я пытаюсь сравнить параметр функции внутри оператора constexpr-if.
Вот простой пример:
constexpr bool test_int(const int i) {
if constexpr(i == 5) { return true; }
else { return false; }
}
Однако, когда я компилирую это с GCC 7 со следующими флагами:
g++-7 -std=c++1z test.cpp -o test
Я получаю следующее сообщение об ошибке:
test.cpp: In function 'constexpr bool test_int(int)':
test.cpp:3:21: error: 'i' is not a constant expression
if constexpr(i == 5) { return true; }
Однако, если я заменю test_int
с другой функцией:
constexpr bool test_int_no_if(const int i) { return (i == 5); }
Затем следующий код компилируется без ошибок:
int main() {
constexpr int i = 5;
static_assert(test_int_no_if(i));
return 0;
}
Я не понимаю, почему не удается скомпилировать версию constexpr-if, тем более что static_assert работает просто отлично.
Любые советы по этому вопросу будут оценены.
Спасибо!
От constexpr если:
В выражении constexpr if значение условия должно быть
контекстно преобразован постоянное выражение типа bool.
Тогда из постоянное выражение:
Определяет выражение, которое может быть оценено во время компиляции.
Очевидно, что i == 5
не является постоянным выражением, потому что i
это параметр функции, который оценивается во время выполнения. Вот почему компилятор жалуется.
Когда вы используете функцию:
constexpr bool test_int_no_if(const int i) { return (i == 5); }
затем он может быть оценен во время компиляции в зависимости от того, известен ли его параметр во время компиляции или нет.
Если i
определяется как:
constexpr int i = 5;
тогда значение i
известно во время компиляции и test_int_no_if
может быть вычислено и во время компиляции, что позволяет вызывать его внутри static_assert
,
Также обратите внимание, что параметр функции маркировки как const
не делает его постоянной времени компиляции. Это просто означает, что вы не можете изменить параметр внутри функции.
Функция constexpr может быть вызвана с аргументами не-constexpr, и в этом случае она ведет себя как обычная функция, поэтому код должен по-прежнему компилироваться, как если бы он не был constexpr.
Короче говоря, в test_int_no_if нет ничего, что зависит от того, являюсь ли я constexpr, а в test_int () — есть. («constexpr if» работает только с выражениями времени компиляции.)