Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:
Так вот, стандартный подход с always_false тут не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Здравствуйте, Videoman, Вы писали:
V>Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
V>Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:
V>Так вот, стандартный подход с always_false тут не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Ну да, для того, чтобы это сработало, компилятор должен исключить этот static_assert из компиляции. А у него для этого нет поводов. Тут нужно как-то адаптировать дизайн. Например, обернуть в constexpr if:
Здравствуйте, Videoman, Вы писали:
V>Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
V>Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:
V>Так вот, стандартный подход с always_false тут не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Интуиция подсказывает, что здесь можно как-то с пользой использовать атрибут assume, но что-то не соображу, как именно.
--
Справедливость выше закона. А человечность выше справедливости.
Делал именно таким методом, но было подумал, что занимаюсь извращением и как-то сложно получается. Вот решил спросить у более опытных коллег. Интересно имменно в рамках 20-го стандарта.
Тут масса вариавнов: можно через pair, можно через option, но в любом случае, приходится городить массу кода для преобразования типов исключений в сообщения об ошибках.
Здравствуйте, Videoman, Вы писали:
V>Делал именно таким методом, но было подумал, что занимаюсь извращением и как-то сложно получается. Вот решил спросить у более опытных коллег. Интересно имменно в рамках 20-го стандарта.
Ну, ждём более опытных
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, so5team, Вы писали:
S>А как в рамках C++20 (и даже C++23) бросить исключение в compile-time?
Также как с выделением памяти. Если весь процесс остается внутри и все сайд эффекты compile-time, но всё работает. Сама внешняя функция noexcept, наружу ничего не летит.
Здравствуйте, Videoman, Вы писали:
S>>А как в рамках C++20 (и даже C++23) бросить исключение в compile-time?
V>Также как с выделением памяти. Если весь процесс остается внутри и все сайд эффекты compile-time, но всё работает. Сама внешняя функция noexcept, наружу ничего не летит.
Простите, понятнее не стало. В C++20 разве можно написать constexpr-функцию, которая бросает исключение в compile-time?
А если нет, то зачем защищаться от исключений, которые в compiler-time могут возникнуть, если возникнуть им неоткуда?
Здравствуйте, Videoman, Вы писали:
V>Здравствуйте, so5team, Вы писали:
V>Ну запутали, так запутали!!!
Простите, не понял, что означает ваш ответ с фейспалмом.
И получается какая-то странная ситуация: вы задаете вопрос, я пытаюсь набросать решение и сталкиваюсь с тем, что не могу его протестировать, т.к. в C++20 (C++23) нет возможности бросить исключение из constexpr-функции в компайл-тайм. Понимаю, что чего-то не понимаю в постановке задачи, задаю уточняющие вопросы, а в ответ фейспалм.
Здравствуйте, Videoman, Вы писали:
V>Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений. Стало удобно, но появилась следующая проблема:
V>Есть функция func1(), которая без проблем работает в constexpr режиме и есть внешняя функция func2(), которая никогда не должна выкидывать исключения, которая вызывает внутри себя первую, типа такого:
V>Так вот, стандартный подход с always_false тут не прокатывает и static_assert срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Здравствуйте, so5team, Вы писали:
S>Простите, не понял, что означает ваш ответ с фейспалмом.
Да я не вам вообще, я на ситуацию в общем.
Я только погружаюсь в 20-й стандарт. Просто задал вопрос, а вы мне в ответ тоже вопрос, да еще как-то неуверенно, может/не может кидать исключения
Из-за того, что не понятно сработают на этапе компиляции constexpr выражения или нет, у меня возникла путаница в коде в котором вперемешку constexpr/не constexpr реализация через std::is_constant_evaluated.
Теперь мне понятно как это работает:
в runtime версии возможно throw, а в constexpr — нет, но просто синтаксис try блоков теперь не отпугивает компилятор.
После паузы я и написал — как все запутано в стандарте.
Здравствуйте, Videoman, Вы писали:
V>Я только погружаюсь в 20-й стандарт. Просто задал вопрос, а вы мне в ответ тоже вопрос, да еще как-то неуверенно, может/не может кидать исключения
У меня у самого путаница в стандартах: в каких-то разрешили динамическую память в виде std::string (вроде бы в C++23), в каких-то вроде как и выброс исключений в compile-time разрешили (емнип, в C++26).
Поэтому если смотреть на самые свежие стандарты, то вроде как там можно столкнуться с проблемой, про которую вы спрашиваете. И может быть вы хотите сейчас, уже в рамках C++20 защититься о того, что добавили в С++26. Но проверить гипотетическое решение в рамках C++20 (и вроде бы даже в рамках C++23) не представляется возможным, т.к. в этих стандартах constexpr-функции не бросают исключений.
V>После паузы я и написал — как все запутано в стандарте.
Да не, вроде бы в конкретном стандарте все более-менее. А вот если пытаться прикидывать на перспективу, на тот же C++26, который когда-нибудь компиляторами будет поддержан, то да, становится запутанно.
Здравствуйте, so5team, Вы писали:
S>Поэтому если смотреть на самые свежие стандарты, то вроде как там можно столкнуться с проблемой, про которую вы спрашиваете. И может быть вы хотите сейчас, уже в рамках C++20 защититься о того, что добавили в С++26. Но проверить гипотетическое решение в рамках C++20 (и вроде бы даже в рамках C++23) не представляется возможным, т.к. в этих стандартах constexpr-функции не бросают исключений.
Не, так далеко я не заглядываю. Действуем потихоньку, сначала 20-й, дальше посмотрим.
Для меня главные две фишки С++20 сейчас, это std::is_constant_evaluated() и concept`ы. Вот и возникают некоторые вопросы, возможно уже всем понятные, по мере переползания на новый стандарт.
А ваши контор-вопросы меня просто в тупик поставили и пришлось самому погружаться в тему и разбираться, поэтому и не смог ничего внятного ответить.
Здравствуйте, Videoman, Вы писали:
V>А ваши контор-вопросы меня просто в тупик поставили и пришлось самому погружаться в тему и разбираться, поэтому и не смог ничего внятного ответить.
Здравствуйте, Videoman, Вы писали:
V>Писать в одной функции две ветки кода, одна для вычисления на уровне компиляции, а другая в run-time.
Я вот тоже не очень понимаю, какую пользу можно извлечь из возможности писать try-catch в constexpr функции. Что может бросить исключение из того, что допустимо использовать внутри функции? А если ничего не может, то зачем тогда try-catch?
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
V>>Писать в одной функции две ветки кода, одна для вычисления на уровне компиляции, а другая в run-time.
R>Я вот тоже не очень понимаю, какую пользу можно извлечь из возможности писать try-catch в constexpr функции. Что может бросить исключение из того, что допустимо использовать внутри функции? А если ничего не может, то зачем тогда try-catch?
А возможен ли такой сценарий: у человека была обычная функция, которая содержала внутри себя try-catch, но которую хотелось иметь еще и в виде constexpr, но раньше нельзя было это делать, т.к. там были try-catch.
Грубо говоря, было:
template<typename T>
int f() {
try {
return T::some_func();
}
catch(...) {
// Ну не шмогли, ну и ладно.return 0;
}
}
Теперь такая возможность появляется (т.е. функцию f из примера выше можно объявить constexpr) но не хочется "проглатывать" исключения, если они происходят в compile-time.