Сравнение параметра функции constexpr в условии constexpr-if вызывает ошибку

Я пытаюсь сравнить параметр функции внутри оператора 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 работает просто отлично.

Любые советы по этому вопросу будут оценены.

Спасибо!

1

Решение

От 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 не делает его постоянной времени компиляции. Это просто означает, что вы не можете изменить параметр внутри функции.

6

Другие решения

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

Короче говоря, в test_int_no_if нет ничего, что зависит от того, являюсь ли я constexpr, а в test_int () — есть. («constexpr if» работает только с выражениями времени компиляции.)

1

По вопросам рекламы [email protected]