noexcept 运算符编译时检查

noexcept operator compile-time check

在下面的代码中,我试图对函数使用条件异常规范,但编译失败,尽管如果在函数外部使用它工作得很好。

void may_throw();

// ERROR: expression must have bool type or be convertible to bool
void check () noexcept(may_throw());

int main()
{
    // works just fine!
    std::cout << noexcept(may_throw());
}

问题是如何在不更改函数原型以有条件地指定的情况下检查函数是否抛出 noexcept?

我无法更改函数原型,因为重点是检查函数是否抛出异常 return true 或 false。

编辑

我想取笑 noexcept,但它似乎不适用于 宏。

#include <iostream>

#if 0
#define ASDF(...) (void)0
#else
#define ASDF(...) throw 1
#endif

void check() noexcept(noexcept(ASDF()))
{
    // wrong!
    // std::cout << noexcept(noexcept(ASDF()));

    // edit: it should be this, and it works.
    // (tnx: StoryTeller-UnslanderMonica)
    std::cout << noexcept(ASDF());
    ASDF(0);
}

int main()
{
    check();
}

给定 void check () noexcept(may_throw());noexcept specifier 期望表达式可转换为 bool,而 may_throw() returns void 不能转换为bool.

您应该在 may_throw() 上应用 noexcept operator 并将其指定为 noexcept 说明符。即

// whether check is declared noexcept depends on if the expression
// may_throw() will throw any exceptions
void check () noexcept(noexcept(may_throw()));
//            ^^^^^^^^          -> specifies whether check could throw exceptions 
//                     ^^^^^^^^ -> performs a compile-time check that returns true if may_throw() is declared to not throw any exceptions, and false if not.

正确的做法是:

noexcept( noexcept( may_throw() ) )

至于为什么,第一个noexcept定义为noexcept-specifier。这用于判断函数是否为 noexcept。它具有以下形式(来自 [except.spec]):

noexcept-specifier:
    noexcept ( constant-expression )
    noexcept
    throw ( )

第二种,是noexcept-operatornoexcept运算符决定是否对其操作数进行求值,即未求值的操作数 (8.2), 可以抛出异常 (18.1). from [expr.unary.noexcept]