истории). В случае написания низкоуровневых (библиотечных) шаблонных абстракций есть ли какие-то best practice по выбору способа перехвата ошибок на этапе компиляции?
- Подход sfinae-friendly: пишем (псевдо)концепты и/или отключаем инстанцирования неугодных функций через enable_if. Плюсы: корректная работа всевозможных стандартных или самодельных трейтов типа is_nothrow_constructible, is_assignable и проч.; минусы: неудобоваримые сообщения об ошибках (пачка "Нимагу подставить, некомпилица"), если все условия запихнуть в одну constexpr bool функцию (если нет C++20 с настоящими концептами), или необходимость писать свой enable_if на каждое условие, чтобы хоть как-то найти нарушение.
- Подход static_assert: разрешаем инстанцирование, а в теле (или до тела в шаблонных дефолтах a la enable_if) вызываем constexpr-функци(и/ю) проверки, где пишем все необходимые static_assert'ы. Плюсы: аккуратные сообщения об ошибках ("Сужающее преобразование запрещено"), минусы: все трейты фейлятся (обманывают), а проверки выстреливают только при попытке инстанцирования (что, наверное, вообще может произойти в соседнем TU, когда остальной код уже скомпилирован, какой-нибудь is_nothrow_move_constructible для vector).
Поискал в истории, тема несколько раз всплывала (спасибо, @webreh), и, как понимаю, первый вариант считается более предпочтительным.
Это же не два конкурирующих подхода, у них разные области применимости.
Обсуждают сегодня