【问题标题】:Are special member functions noexcept or throw()?特殊成员函数是 noexcept 还是 throw()?
【发布时间】:2012-10-14 01:12:34
【问题描述】:

C++11 规范明确隐式生成的特殊函数(即默认构造函数、析构函数、复制/移动构造函数和复制/移动赋值运算符)具有异常规范。但该规范似乎仅根据现已弃用的 dynamic 异常规范(即“throw (T1, T2, T3)”)编写。 15.4/14 中的示例支持这一点:

struct A {
  A();
  A(const A&) throw();
  A(A&&) throw();
  ~A() throw(X);
};
struct B {
  B() throw();
  B(const B&) throw();
  B(B&&) throw(Y);
  ~B() throw(Y);
};
struct D : public A, public B {
  // Implicit declaration of D::D();
  // Implicit declaration of D::D(const D&) throw();
  // Implicit declaration of D::D(D&&) throw(Y);
  // Implicit declaration of D::D() throw(X, Y);
};

注释并不规范,我知道,但值得注意的是,D 的复制构造函数声明为 throw() 而不是 noexcept。这会有所不同,因为如果违反了 throw() 与违反了 noexcept ,程序的行为是不同的。

上面例子中15.4/14的文字是规范的,上面写着:

隐式声明的特殊成员函数(第 12 条) 应具有异常规范。如果 f 是隐式声明的 默认构造函数,复制构造函数,移动构造函数,析构函数, 复制赋值运算符,或移动赋值运算符,其隐式 exception-specification 指定类型 ID T 当且仅当 T 是 由直接调用的函数的异常规范所允许 由 f 的隐含定义; f 应允许所有例外情况(如果有) 它直接调用的函数允许所有异常,并且 f 应允许 如果它直接调用的每个函数都不允许 例外。

鉴于这里只提到了动态异常规范,我担心隐式生成的特殊成员函数永远不会被声明为noexcept。真的是这样吗?

【问题讨论】:

  • 他们怎么可能被声明为noexcept?您是否希望编译器检查您的代码并检查您是否从未抛出异常?
  • @SethCarnegie:如果编译器推断出动态异常规范为throw(),我希望编译器使用noexcept
  • 由于“12 [...] 具有不抛出异常规范的函数不允许任何异常。”,noexceptthrow() 中的任何一个都是有效的异常规范这不允许任何例外。这对于第 14 段来说似乎已经足够了,它特别不需要动态异常规范。我不确定我是否能很好地掌握整个情况以做出回答。
  • “这会有所不同,因为如果违反了 throw() 和违反了 noexcept,程序的行为是不同的。”真的吗?怎么样?
  • @Nemo 程序的行为在throw()noexcept违规 的情况下有所不同,即如果实际抛出异常。 noexcept 调用 std::terminate,在这种情况下可能没有完全展开堆栈。

标签: c++ c++11


【解决方案1】:

我认为情况并非如此。实际的要求只是“...f 如果它直接调用的每个函数都不允许异常,则不应允许异常。”

如上所述(§15.4/12):

如果是throw()noexceptnoexcept(constant-expression) 的形式,则异常规范是不抛出的,其中 constant-expression 产生true。具有不抛出异常规范的函数不允许任何异常。

非抛出异常规范不允许任何异常并不完全是一个启示,但我认为它说明了非抛出异常规范描述中的措辞在隐式声明的要求中几乎一字不差地呼应了特殊的成员函数。因此,在我看来,任何形式的非抛出异常规范(throw()noexceptnoexcept(<anything that converts to true>))都是允许的——而且这是专门设计的,而不仅仅是措辞上的意外。

【讨论】:

  • 我可以看到您如何以这种方式阅读它,但鉴于 noexceptthrow() 之间的语义差异,如果标准更准确地说明使用哪个来表达就好了函数不会抛出的概念。
猜你喜欢
  • 2012-01-27
  • 2013-09-14
  • 2023-03-05
  • 2017-01-09
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 2016-06-26
相关资源
最近更新 更多