使用 noexcept 运算符链接 noexcept 声明

Using the noexcept operator to chain noexcept declarations

为什么 noexcept 运算符采用表达式而不是函数 signature/declaration?

考虑以下虚拟示例:

#include <string>

void strProcessor(const std::string& str) noexcept(true) { };

struct Type{
  void method1() noexcept(strProcessor("")) { //Error: Call to nonconstexpr function
     strProcessor("");
  }
};

它不会编译,因为 method1 在其 noexcept 中有一个非 constexpr 表达式,但为什么我首先需要在其中放置一个表达式?

我想做的就是告诉编译器 method1 是 noexcept 当且仅当使用成功构造的字符串调用 strProcessor 是 noexcept(这它是)。

那为什么不noexcept(void strProcessor(const std::string&))呢?

另一个类似的虚拟示例:

struct Type{
   Type(bool shouldThrow=false) noexcept(false) { if(shouldThrow) throw "error"; };
   void method1() noexcept(true) {};
   void method2() noexcept(noexcept(Type().method1())) { method1(); };
}

在这里我想说 method2 是 noexcept iff 在成功构造的 Type 实例上调用 method1 是 noexcept(它在在这种情况下),但是 Typemethod2 id 定义的地方甚至还没有完成。

如果我对这个功能的理解有误,请解释。

void method1() noexcept(noexcept(strProcessor(""))) {
//   Second 'noexcept'  ^^^^^^^^^                ^

第一个是 noexcept specifier,它 指定 method1() 是否 noexcept

嵌套的是 noexcept operator,它 检查 当用 "".

你的第二种情况有点棘手:Type 在我们想在 noexcept 中使用 method1() 的地方仍然不完整。我来到以下解决方法,滥用指向成员的指针:

void method2() noexcept(noexcept(
    (std::declval<Type>().*&Type::method1)()
)) {};

但是,我不认为存在只能从 method1() 的规范中推导出 method2()noexcept 规范的情况。

如果在检查函数的 noexceptness 时需要一些语法糖,可以使用如下辅助函数:

template <typename R, typename... Params>
constexpr bool is_noexcept(R(*p)(Params...)) {
    return noexcept(p(std::declval<Params>()...));
}

并如此申请:

void method1() noexcept(is_noexcept(strProcessor)) …

Demo.