static_assert в catch секции
От: Videoman Россия https://hts.tv/
Дата: 21.12.24 12:25
Оценка:
Как известно в С++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 срабатывает всегда, а мне нужно что бы он срабатывал только если возникло исключение. Как такое можно организовать?
Отредактировано 21.12.2024 13:19 Videoman . Предыдущая версия .
Re: static_assert в catch секции
От: rg45 СССР  
Дата: 21.12.24 14:44
Оценка: 6 (1)
Здравствуйте, 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>();
}
--
Справедливость выше закона. А человечность выше справедливости.
Re: static_assert в catch секции
От: rg45 СССР  
Дата: 21.12.24 14:49
Оценка:
Здравствуйте, 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, но что-то не соображу, как именно.
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: static_assert в catch секции
От: Videoman Россия https://hts.tv/
Дата: 21.12.24 15:03
Оценка:
Здравствуйте, rg45, Вы писали:

R>...


Делал именно таким методом, но было подумал, что занимаюсь извращением и как-то сложно получается. Вот решил спросить у более опытных коллег. Интересно имменно в рамках 20-го стандарта.
Тут масса вариавнов: можно через pair, можно через option, но в любом случае, приходится городить массу кода для преобразования типов исключений в сообщения об ошибках.
Отредактировано 21.12.2024 15:06 Videoman . Предыдущая версия .
Re[3]: static_assert в catch секции
От: rg45 СССР  
Дата: 21.12.24 15:05
Оценка: :)
Здравствуйте, Videoman, Вы писали:

V>Делал именно таким методом, но было подумал, что занимаюсь извращением и как-то сложно получается. Вот решил спросить у более опытных коллег. Интересно имменно в рамках 20-го стандарта.


Ну, ждём более опытных
--
Справедливость выше закона. А человечность выше справедливости.
Re: static_assert в catch секции
От: so5team https://stiffstream.com
Дата: 22.12.24 05:45
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Как известно в С++20 подвезли возможность использовать try catch блоки внутри constexpr выражений.


А как в рамках C++20 (и даже C++23) бросить исключение в compile-time?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.