我正在用C ++ 11编写一个小程序,并且第一次真正使用异常。
我有一个关于如何有效捕捉异常的问题,经过一些谷歌搜索后,我仍然没有答案。
以下是问题: 通过(const?)左值引用或(const?)rvalue引用捕获异常之间的效率(或建议)是什么?
在代码中,这给出了:
1)
try { throw std::exception{"what"}; }
catch (std::exception& ex) {}
2)
try { throw std::exception{"what"}; }
catch (const std::exception& ex) {}
3)
try { throw std::exception{"what"}; }
catch (std::exception&& ex) {}
4)
try { throw std::exception{"what"}; }
catch (const std::exception&& ex) {}
答案 0 :(得分:32)
你应该通过const lvalue reference(2)来捕获:
try { throw std::exception{"what"}; }
catch (const std::exception& ex) {}
理由:
在C ++ 11中,有可能(通过使用shared_future
)两个线程可以同时展开同一个异常。即使您不知道正在使用shared_future
,您的代码也可能发生这种情况,除非您控制整个应用程序。
如果捕获到两个线程同时展开同一个异常,并且其中一个或两个线程修改了异常,那么你就会遇到竞争条件。
因此,只要您不必修改catch子句中的异常对象,就让编译器为您强制执行该策略 - 由const&
捕获。如果确实需要修改异常,则复制它,修改副本并抛出副本。如果您确定不会对异常对象进行切片(如果您捕获std::exception
通常不是这种情况),则可以通过按值捕获来执行此操作。
答案 1 :(得分:1)
我认为应该通过lvalue-reference以通常的方式捕获异常。 Here's对rvalues-references的良好解释使用