nij*_*sen 5 c++ throw noexcept c++11
在C++ 11中,这是不推荐使用的:
void foo() throw();
Run Code Online (Sandbox Code Playgroud)
并替换为
void foo() noexcept;
Run Code Online (Sandbox Code Playgroud)
在本文中,我们解释了其中的原因(其中包括归结为同样的事情)
在运行时而不是在编译时检查C++异常规范,因此它们不提供程序员保证已处理所有异常.
虽然这对我有意义,但我不明白为什么throw()首先动态检查,或者为什么noexcept除了调用std::terminate而不是正常的堆栈展开之外不提供异常保证(这实际上不是IMO的坚实保证).
如果发生这种情况,是否有可能在编译期间检查是否抛出异常并且编译失败?我认为,基本上有三种情况:
void foo() noexcept
{
// 1. Trivial case
throw myexcept();
// 2. Try-catch case
// Necessary to check whether myexcept is derived
// from exception
try
{
throw myexcept();
}
catch(exception const & e)
{}
// 3. Nested function call
// Recursion necessary
bar();
}
Run Code Online (Sandbox Code Playgroud)
使用C++中的模板为每种类型实例化,编译应用程序仍然需要永远 - 所以为什么不改变noexcept以强制编译器检查在编译期间是否抛出异常?
我看到的唯一困难是函数可能会或可能不会根据运行时状态抛出 - 但noexcept在我看来,不应该允许该函数调用自身.
我是否遗漏了某些东西,或者是不打算进一步增加编译时间,还是想让编译器开发人员轻松一点?
我认为这很大程度上归结于这样一个事实:当定义异常规范时,编译器编写者远远落后于能力曲线。实现 C++98 非常复杂,以至于只有一个编译器声称实现了其所有功能。其他所有编译器都至少遗漏了标准中包含的一项主要功能。大多数人相当公开地承认,他们遗漏的远不止这些。
您还需要记住,动态异常规范也比仅仅复杂得多throw()。它允许程序员指定可以抛出的任意类型集。更糟糕的是,指定一个函数可以抛出foo意味着它也可以抛出任何派生的东西foo。
静态地执行异常规范是可以做到的,但它显然会增加相当多的额外工作,而且没有人真正确定它会提供什么(如果有的话)好处。在这种情况下,我认为大多数人很容易认为静态强制是以后可能需要的东西,如果似乎有足够的用途来证明这项工作的合理性。从运行时强制更改为编译时强制不需要修改现有代码,只需要修改现有实现。
另一点是,我不确定是否有过对异常规范的真正强有力的支持。我认为人们对基本想法达成了普遍共识,但当你认真思考时,可能对细节的了解较少。
底线:很容易只强制执行动态执行,并将静态执行留到以后(如果有的话)。事实证明,静态强制执行在任何情况下都可能不会真正带来那么多积极效果,因此强制执行它可能不会取得多大成果。
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |