`inline` 和 `noexcept` 在consteval上下文中是多余的吗?

Are `inline` and `noexcept` redundant in a consteval context?

我正在处理一些代码,其中使用了 constexpr 函数,我目前尽可能将其重构为 consteval

inline constexpr auto example() noexcept { /*...*/ }

As I understand it,上面的inline关键字在constexpr函数中已经是多余的了

据我了解,noexcept 关键字对于 consteval 函数是多余的,因为据我了解,consteval 必须在编译时求值,因此意味着没有例外。这是真的还是可能有一些我目前没有考虑的东西(比如 constexpr exceptions)?

consteval auto example() { /*...*/ }

inline 是多余的,因为:[dcl.constexpr]/1:

A function or static data member declared with the constexpr or consteval specifier is implicitly an inline function or variable ([dcl.inline]).


noexcept 比较有趣。的确,在常量评估时间 ([expr.const]/5.24) 期间不允许尝试抛出异常(无论是通过 throwdynamic_cast 还是 typeid)。并且由于 consteval 函数仅 在持续评估时间内评估,因此 noexcept 的好处微乎其微 - 异常肯定永远不会超出此范围。而且,您甚至不能让指向这些函数的函数指针泄漏到运行时。我真的没有想到与此相关的机制。

但是,也许在未来的某个时候,我们是否可以允许在不断评估期间出现异常?如果我们去那里,了解那个世界的 noexcept-ness 会变得很重要吗?从常量评估上下文中泄漏的异常可能意味着编译错误,那么您是否可以使用基于 consteval 函数的 noexcept-ness 做出不同选择的算法?

也就是说,我会跳过 noexcept。现在肯定没有好处,以后可能连好处都没有。如果我最终错了那么……对不起。

虽然真的如T.C。指出,事情没那么简单:

consteval int current() { return 1; }
void f(int, int = current()) noexcept;

什么是 noexcept(f(1))?正如所写,它是 false。这很奇怪,因为这个表达式 f(1) 肯定不会抛出。所以也许你应该写 noexcept。尽管从那以后它肯定不能抛出,也许语言应该默认使 consteval 函数 noexcept 。尽管如果我们这样做,并最终在不断的评估时间内添加异常……现在我们又回到了撒谎,因为那是我们无法收回的东西。