简而言之,是否有可能让C ++强制一个方法的调用者放一个try ... catch块?
(澄清: 我不一定意味着直接的调用者,我的意思是强迫它被抓到了某个地方。另外,我正在谈论在编译时强制执行。)
长:
我已经读过不建议使用异常规范,并且它无论如何都不能正常工作(http://4thmouse.com/mystuff/articles/UsingExceptionsEffectively.html)
但普遍的共识似乎倾向于使用异常来返回写入返回错误代码的方法的用户的错误。
因此,如果我正在写一个库,那么阻止用户调用我的方法而不放任何try ... catch块,然后当我的代码抛出异常时让他的程序崩溃是什么?
(要明确的是,我只需要在用户堆栈中的某处捕获异常,不一定在即时调用代码中,并且编译器如果不是这样则会抱怨。)
答案 0 :(得分:10)
不,不是。
实际上,没有任何机制可以强制函数的调用者(调用堆栈中的任何位置)处理任何类型的错误。至少,不是通过编译失败。可以丢弃返回值。即使使用返回值捆绑错误代码(通过expected<T, E>
)也不会发出编译时错误,如果用户在获取之前没有实际检查该值是否可用。
C ++ 17可能会给我们[[nodiscard]]
属性,如果调用者丢弃了返回值(可能是错误代码),它允许编译器发出警告。但编译时警告将尽可能接近。
答案 1 :(得分:1)
简而言之,是否有可能让C ++强制调用方法 尝试一下......抓住一块?
没有。这将破坏例外的整个目的。特别针对多个图层中传播错误的用例进行了例外处理,而没有中间层知道它们。
我们假设您有一个类似A的呼叫层次结构 - > B - &gt; C - &gt; D - &gt; E,并且在E中发生错误.A可以处理错误。 B,C和D 根本不需要知道错误。这正是例外情况的好处!
如果要将错误直接返回给调用者,因为处理错误确实是调用者关注的问题,那么异常通常是错误的设计,返回值可能是更好的选择。
&#34;强迫&#34;已经在Java中尝试过某种形式的异常,但我认为这是一个失败的实验,因为它通常会产生如下代码:
try {
method();
} catch (SomeCheckedException ex) {
// ignore
}
C ++不鼓励这应该被视为功能。
我已经读过不建议使用异常规范和 它无论如何都不能正常工作
完全。唯一有用且有效的异常规范是throw()
表示根本没有引发任何异常,并且noexcept
已经在C ++ 11中取代了它。
但普遍的共识似乎倾向于使用例外 返回写入返回错误的方法的用户的错误 码。
见上文。这取决于您是否希望传播错误,或者调用者是否能够并且应该处理它。
因此,如果我写一个图书馆,那么阻止用户打电话的原因是什么 我的方法没有尝试...抓住块,然后得到他的 我的代码抛出异常时程序崩溃了吗?
要求用户使用try
块来包围所有函数调用的库具有错误的接口,因此应该重新设计。
另外......你假设一个&#34;程序&#34;将使用您的图书馆。但这种假设并不总是正确的。库客户端本身可以是库。程序和库之间可能有很多不同的库层。如果您不关心哪个图层处理它们,则使用例外。
答案 2 :(得分:0)
有一个普遍的共识吗?不是我意识到的。至于例外,没有。编译器无法强制某人在调用堆栈的某处捕获异常。在编译时,编译器不知道谁可能正在调用您的函数,并且您的函数可能抛出任何异常,就像函数调用的任何函数一样。链接器可能有机会,但它必须维护大量额外信息,以处理函数可能抛出的异常,以及函数可能捕获的异常。当你开始谈论动态加载的库(DLL / .so)时,这会变得更加丑陋,因为它必须在运行时得到解决。