Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:
template<typename...>
inline constexpr bool always_false = false;
template<typename type_t>
constexpr int func2() noexcept
{
try {
return func1();
} catch (...) {
static_assert(always_false<type_t>, "error!");
return 0;
}
}
Так вот, стандартный подход с always_false тут
не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Здравствуйте, Videoman, Вы писали:
V>Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
V>Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:V>template<typename...>
V>inline constexpr bool always_false = false;
V>template<typename type_t>
V>constexpr int func2() noexcept
V>{
V> try {
V> return func1();
V> } catch (...) {
V> static_assert(always_false<type_t>, "error!");
V> return 0;
V> }
V>}
V>
V>Так вот, стандартный подход с always_false тут не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Ну да, для того, чтобы это сработало, компилятор должен исключить этот static_assert из компиляции. А у него для этого нет поводов. Тут нужно как-то адаптировать дизайн. Например, обернуть в constexpr if:
http://coliru.stacked-crooked.com/a/d21b3db809532a31
#include <exception>
#include <utility>
template<typename...>
inline constexpr bool always_false = false;
constexpr int func1()
{
return 1;
}
template<typename type_t>
constexpr int func2() noexcept
{
constexpr auto call_func1 = []() -> std::pair<int, bool> {
try {
return {func1(), true};
} catch (...) {
return {};
}
};
constexpr auto res = call_func1();
if constexpr (res.second) return res.first;
else static_assert(always_false<type_t>, "error!");
}
int main()
{
return func2<int>();
}
Здравствуйте, Videoman, Вы писали:
V>Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
V>Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:V>template<typename...>
V>inline constexpr bool always_false = false;
V>template<typename type_t>
V>constexpr int func2() noexcept
V>{
V> try {
V> return func1();
V> } catch (...) {
V> static_assert(always_false<type_t>, "error!");
V> return 0;
V> }
V>}
V>
V>Так вот, стандартный подход с always_false тут не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Интуиция подсказывает, что здесь можно как-то с пользой использовать атрибут
assume, но что-то не соображу, как именно.
Здравствуйте, rg45, Вы писали:
R>...
Делал именно таким методом, но было подумал, что занимаюсь извращением и как-то сложно получается. Вот решил спросить у более опытных коллег. Интересно имменно в рамках 20-го стандарта.
Тут масса вариавнов: можно через pair, можно через option, но в любом случае, приходится городить массу кода для преобразования типов исключений в сообщения об ошибках.
Здравствуйте, Videoman, Вы писали:
V>Делал именно таким методом, но было подумал, что занимаюсь извращением и как-то сложно получается. Вот решил спросить у более опытных коллег. Интересно имменно в рамках 20-го стандарта.
Ну, ждём более опытных