Являются ли ʻinline` и `noexcept` избыточными в контексте consteval?
Я работаю с кодом, в котором constexpr
используются функции, которые я в настоящее время рефакторую consteval
когда возможно.
inline constexpr auto example() noexcept { /*...*/ }
Насколько я понимаю,inline
ключевое слово выше уже является избыточным в constexpr
функция.
Насколько я понимаю, noexcept
ключевые слова являются избыточными для consteval
функции, потому что я так понимаю consteval
должен оцениваться во время компиляции и, следовательно, не подразумевает исключения. Это правда или есть что-то, что я в настоящее время не рассматриваю (например, constexprexceptions
)?
consteval auto example() { /*...*/ }
1 ответ
inline
является избыточным, потому что: [dcl.constexpr] / 1:
Функция или статический член данных, объявленный с
constexpr
илиconsteval
спецификатор неявно является встроенной функцией или переменной ([dcl.inline]).
noexcept
несколько интереснее. Это правда, что попытка выбросить исключение (будь то черезthrow
, dynamic_cast
, или typeid
) не допускается в течение постоянного времени оценки ([expr.const]/5.24). А посколькуconsteval
функция оценивается только в течение постоянного времени оценки,noexcept
имеет минимальную выгоду - исключение никогда не ускользнет из этой области. И, более того, у вас даже не может быть указателя на функцию для утечки этих функций во время выполнения. На самом деле я не могу придумать механизма, для которого это было бы актуально.
Однако, возможно, в какой-то момент в будущем нам разрешат делать исключения во время постоянной оценки? И если мы пойдем туда, станет ли важно знать оnoexcept
-ность в этом мире? Исключение, которое просачивается из постоянного контекста оценки, вероятно, должно означать ошибку компиляции, поэтому, возможно, у вас есть алгоритмы, которые делают другой выбор на основеnoexcept
-констевальная функция?
Тем не менее, я бы пропустил noexcept
. Это определенно не приносит пользы сейчас, и, возможно, даже не принесет пользы в будущем. И если я в конечном итоге ошибаюсь, тогда... Мне очень жаль.
Хотя на самом деле, как указывает TC, все не так просто:
consteval int current() { return 1; }
void f(int, int = current()) noexcept;
Что noexcept(f(1))
? Как написано, этоfalse
. И это довольно странно, так как это выражениеf(1)
точно не собираюсь бросать. Так что, может, тебе стоит написатьnoexcept
. Хотя раз уж точно бросить нельзя, может язык должен сделатьconsteval
функции noexcept
по умолчанию. Хотя, если мы сделаем это и в конечном итоге добавим исключения в течение постоянного времени оценки... теперь мы снова будем лгать, поскольку это то, что мы не сможем вернуть.