При вычислении постоянных выражений для инициализации a constexpr
можно исключать исключения. Например, вот пример, когда вычисление постоянного выражения защищено от переполнения:
#include <iostream>
#include <stdexcept>
constexpr int g(int n, int n0, int n1) {
return n == 0? n1: g(n - 1, n1, n0 + n1);
}
constexpr int f(int n) {
return n < 42? g(n, 0, 1): throw std::out_of_range("too big");
}
int main()
{
try {
constexpr int f41 = f(41); // OK: constexpr
int f43 = f(43); // OK: throws an exception
constexpr int f42 = f(42); // not OK but what happens?
}
catch (std::exception const& ex) {
std::cout << "ERROR: " << ex.what() << "\n";
}
}
Первый вызов f()
просто показывает, что a constexpr
может быть вычислен. Второй вызов f()
не используется для инициализации constexpr
и генерирует исключение во время выполнения. Третий вызов f()
используется для инициализации constexpr
, но эта точка никогда не будет достигнута, потому что выбрано исключение. Однако что должно произойти в этом случае? Я ожидаю, что обработчик в catch
-clause будет выполнен, но gcc и clang создайте ошибку времени компиляции.