ypn*_*nos 0 c++ exception c++11
我想知道为什么std::current_exception()在这种情况下工作会有所不同:
std::exception_ptr e, e2;
try {
std::string("abcd").substr(42);
} catch(std::exception &ex) {
std::cerr << "(1) Exception: " << ex.what() << std::endl;
e = std::current_exception();
e2 = std::make_exception_ptr(ex);
}
handle_exception(e);
handle_exception(e2);
Run Code Online (Sandbox Code Playgroud)
而handle_exception则打印异常:
void handle_exception(std::exception_ptr e)
{
try {
if (e)
std::rethrow_exception(e);
} catch(const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
(1) Exception: basic_string::substr: __pos (which is 42) > this->size() (which is 4)
(2) Exception: basic_string::substr: __pos (which is 42) > this->size() (which is 4)
(3) Exception: std::exception
Run Code Online (Sandbox Code Playgroud)
但是我希望得到以下输出:
(1) Exception: basic_string::substr: __pos (which is 42) > this->size() (which is 4)
(2) Exception: basic_string::substr: __pos (which is 42) > this->size() (which is 4)
(3) Exception: basic_string::substr: __pos (which is 42) > this->size() (which is 4)
Run Code Online (Sandbox Code Playgroud)
我在这里缺少什么?
throw需要注意的是,C++ throw(我只会讨论它与操作数的用法,例如throw someExpression;)对传递的操作数的类型敏感。它复制其操作数(从中复制初始化辅助对象)。复制是根据操作数的(词法)类型完成的(而不是通过动态获取类)。
例如:
try {
std::runtime_error myException("Some test message");
std::exception &upcastedMyException = myException;
throw upcastedMyException; //std::exception is thrown
} catch(const std::exception &caught) {
std::cout << caught.what() << std::endl; //will output "std::exception"
}
Run Code Online (Sandbox Code Playgroud)
它与其他语言不同,例如Java:
try {
RuntimeException myException = new RuntimeException();
Exception upcastedMyException = myException;
throw upcastedMyException; //RuntimeException is thrown
} catch(Exception caught) {
System.out.println(caught.getClass()); //will output "java.lang.RuntimeException"
}
Run Code Online (Sandbox Code Playgroud)
因此,传递给 C++ 的表达式具有正确的类型非常重要throw。在我的第一个示例中,替换throw upcastedMyException为(例如)throw static_cast<const std::runtime_error &>(upcastedMyException)会更改输出。
std::make_exception_ptrstd::make_exception_ptr另一方面,通过以下方式以非常简单的方式实现throw:
template<class E> std::exception_ptr make_exception_ptr(E e) noexcept {
try {
throw e; //note this line
} catch(...) {
return std::current_exception();
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着std::make_exception_ptr对传递的模板参数敏感;如果未显式传递模板参数,则std::make_exception_ptr对传递的函数参数的(词法)类型敏感(这会影响模板参数的推导):
std::make_exception_ptr(ex)在代码中执行此操作(其中ex声明为const std::exception &),则将std::exception被抛出std::make_exception_ptr并std::make_exception_ptr返回std::exception_ptr与 相关的内容std::exception。std::make_exception_ptr(static_cast<const std::logic_error &>(ex))在代码中这样做,则 thenstd::logic_error将被抛出std::make_exception_ptr并std::make_exception_ptr返回std::exception_ptr与 相关的内容std::logic_error。std::make_exception_ptr(static_cast<const std::out_of_range &>(ex))在代码中这样做,则 thenstd::out_of_range将被抛出std::make_exception_ptr并std::make_exception_ptr返回std::exception_ptr与 相关的内容std::out_of_range。std::make_exception_ptr()按值获取其参数。这意味着复制或就地构建。
您正在制作 std::exception 的副本(即切片)
| 归档时间: |
|
| 查看次数: |
2352 次 |
| 最近记录: |