6

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

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

据我了解,上面的inline关键字在函数中已经是多余的了constexpr

据我了解,noexcept关键字对于consteval函数来说是多余的,因为据我了解,它consteval必须在编译时进行评估,因此意味着 noexcept。这是真的还是我目前不考虑的事情(比如 constexpr exceptions)?

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

1 回答 1

9

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

constexpr使用or说明符声明的函数或静态数据成员consteval隐含地是内联函数或变量 ([dcl.inline])。


noexcept更有趣一些。确实,在恒定评估时间内( [expr.const]/5.24 )不允许尝试抛出异常(无论是 via throwdynamic_cast还是)。而且由于一个函数在恒定的评估时间内进行评估,它的好处很小——一个异常肯定永远不会逃脱这个范围。而且,您甚至不能让指向这些函数的函数指针泄漏到运行时。真的没有我能想到的与之相关的机制。typeidconstevalnoexcept

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

也就是说,我会跳过noexcept. 它现在肯定没有好处,将来甚至可能没有好处。如果我最终错了,那么......我很抱歉。

尽管正如 TC 所指出的那样,这确实不是那么简单:

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

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

于 2020-02-27T15:34:24.743 回答