使用noexcept运算符链接noexcept声明

时间:2015-07-27 13:29:38

标签: c++ c++14

为什么noexcept运算符采用表达式而不是函数签名/声明?

考虑以下虚拟示例:

#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 (它是)。< / p>

那么为什么不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是nocept,如果在一个成功构造的Type的实例上调用method1是noexcept (在这种情况下就是这样),但是在Type id定义的位置,method2甚至没有完成。

请解释我对此功能的理解是否错误。

2 个答案:

答案 0 :(得分:9)

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

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

嵌套的是noexcept operator,当使用strProcessor()调用时,检查 ""是否 noexcept

你的第二个案例有点棘手:Type在我们想要method1()内使用noexcept时仍然不完整。我来到以下解决方法,滥用指向成员的指针:

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

但是,我不认为您只能从method2()推断出method1() noexcept 规范。

答案 1 :(得分:2)

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

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