[英]What does the C++ standard say about overriding a throw() function with noexcept?
The following seems to compile on a couple of compilers that I've tried: 以下似乎是在我试过的几个编译器上编译的:
class A
{
public:
virtual void foo() throw() = 0;
};
class B : public A
{
public:
virtual void foo() noexcept override { }
};
It seems that one can override a throw() function with the newer noexcept specification. 似乎可以使用较新的noexcept规范覆盖throw()函数。 I also tried the opposite (overriding noexcept with throw()) and it seems to work.
我也尝试了相反的方法(用throw()覆盖noexcept)它似乎工作。 Why is that?
这是为什么? Is this undefined behavior or is this allowed?
这是未定义的行为还是允许的?
Please note that code generation is affected by noexcept vs throw(). 请注意,代码生成受noexcept vs throw()的影响。 They also do not have equivalent behavior since noexcept calls a different termination function than throw().
它们也没有相同的行为,因为noexcept调用与throw()不同的终止函数。 An ideal answer will call out the differences in behavior and why they do or do not matter in this case.
一个理想的答案将说明行为的差异以及在这种情况下它们为何或不重要。
You can even do this without overriding: 您甚至可以在不覆盖的情况下执行此操作:
void f() throw();
void f() noexcept { throw 1; }
[except.spec]/9 makes it clear that it is the specification on the definition that controls what happens: [except.spec] / 9清楚地表明, 定义中的规范控制着发生的事情:
Whenever an exception of type E is thrown and the search for a handler ([except.handle]) encounters the outermost block of a function with an exception specification that does not allow E, then,
每当抛出类型E的异常并且搜索处理程序([except.handle])遇到具有不允许E的异常规范的函数的最外面的块时,则,
if the function definition has a dynamic-exception-specification , the function
std::unexpected()
is called ([except.unexpected]),如果函数定义具有动态异常规范 ,则调用函数
std::unexpected()
([except.unexpected]),otherwise, the function
std::terminate()
is called ([except.terminate]).否则,调用函数
std::terminate()
([except.terminate])。
This isn't a problem because whatever special handling for this happens in the callee, not the caller; 这不是问题,因为在被调用者中发生了对此的特殊处理,而不是调用者; all the caller needs to know is that no exception will ever leave the function.
所有调用者需要知道的是,任何例外都不会离开函数。
Is this undefined behaviour or is this allowed?
这是未定义的行为还是允许的? This is allowed.
这是允许的。
From the C++ standard: 从C ++标准:
If a virtual function has an exception specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the exception specification of the base class virtual function, unless the overriding function is defined as deleted.
如果虚函数具有异常规范,则在任何派生类中覆盖该虚函数的任何函数的所有声明(包括定义)应仅允许基类虚函数的异常规范所允许的异常,除非覆盖函数被定义为已删除。
Practically: you can override the method in the derived class and specify new rules in additional to those specified by the base class. 实际上:您可以覆盖派生类中的方法,并指定除基类指定的规则之外的新规则。
In your example throw()
and noexcept
are equivalent. 在您的示例中,
throw()
和noexcept
是等效的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.