将标准::exception_ptr转换为提升::exception_ptr
Converting std::exception_ptr to boost::exception_ptr
我想使用期望boost::exception_ptr
boost::promise::set_exception()
。问题是,只有当我用enable_current_exception
包裹我所有的投掷时,boost:exception_ptr
似乎才能正常工作,我想避免这种情况。(无论如何,我都无法为第三方库执行此操作。我在整个代码中使用std::exception_ptr/std::current_exception
,因此我正在寻找一种方法来传递std::exception_ptr
需要boost:exception_ptr
的地方。执行以下操作但编译的内容:
boost::exception_ptr convert(std::exception_ptr ex) {
try {
std::rethrow_exception(ex);
}
catch(auto& ex) {
try {
throw boost::enable_current_exception(ex);
}
catch (...) {
return boost::current_exception();
}
}
}
你知道怎么做吗?
上下文:
我需要boost::future::then()
,所以不幸的是,使用std::promise
不是一种选择(至少目前)
如果您知道一种方法可以使boost::exception_ptr
依赖于 gcc 4.8 编译器支持而不是enable_current_exception
那也是一个可接受的解决方案。
不幸的是,我认为这是不可能的。但是,我可以为您提供三种可能的解决方案,按便利性排序:
1. 抓住一个标准::异常
boost::exception_ptr convert(std::exception_ptr ex)
{
try {
std::rethrow_exception(ex);
} catch (const std::exception& e) {
try {
throw boost::enable_current_exception(e);
} catch (...) {
return boost::current_exception();
}
} catch (...) {
try {
throw boost::enable_current_exception(std::runtime_error("Unknown exception."));
} catch (...) {
return boost::current_exception();
}
}
}
int main()
{
std::exception_ptr sep;
try {
throw std::runtime_error("hello world");
} catch (...) {
sep = std::current_exception();
}
boost::exception_ptr bep = convert(sep);
try {
boost::rethrow_exception(bep);
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
}
这将打印"std::exception"
而不是"hello world"
,因为来自派生类(在本例中为std::runtime_error
)的信息将被切掉。
2. 直接扔标准::exception_ptr
boost::exception_ptr convert(std::exception_ptr ex)
{
try {
throw boost::enable_current_exception(ex);
} catch (...) {
return boost::current_exception();
}
}
int main()
{
std::exception_ptr sep;
try {
throw std::runtime_error("hello world");
} catch (...) {
sep = std::current_exception();
}
boost::exception_ptr bep = convert(sep);
try {
boost::rethrow_exception(bep);
} catch (const std::exception_ptr& ep) {
try {
std::rethrow_exception(ep);
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
}
}
这个版本打印"hello world"
,尽管代价是额外的try
/catch
块。如果错误处理是在中心位置完成的,可能会显示一个对话框,我会选择这个解决方案。直到 boost 作者添加一个从 std::exception_ptr
到 boost::exception_ptr
的构造函数,恐怕这已经足够好了。
:p ackaged_task 而不是 boost::p romise
如果您可以忍受使用 packaged_task
,此解决方案有效:
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp>
int main()
{
boost::packaged_task<int()> pt([] () -> int {
throw std::runtime_error("hello world");
});
boost::future<int> f1 = pt.get_future();
boost::future<int> f2 = f1.then([] (boost::future<int> f) {
return f.get() + 1;
});
boost::thread(std::move(pt)).detach();
try {
int res = f2.get();
} catch (const std::runtime_error& e) {
std::cout << e.what() << std::endl;
}
}
打印"hello world"
并允许您使用fut.then()
。
我发现不是最好的解决方案,但它有效。
- 克里特岛模板专业化。
namespace boost::exception_detail
{
template<>
class clone_impl< std::exception_ptr > : public clone_base
{
std::exception_ptr mExceptionPtr;
public:
clone_impl( std::exception_ptr exception_ptr )
: mExceptionPtr{ std::move( exception_ptr ) }
{
}
clone_base const* clone() const
{
return new clone_impl( *this );
}
void rethrow() const
{
std::rethrow_exception( mExceptionPtr );
}
};
int clone_current_exception_non_intrusive( clone_base const*& cloned )
{
cloned = new clone_impl< std::exception_ptr >{ std::current_exception() };
return clone_current_exception_result::success;
}
}
- 添加
BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR
定义
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 为重写std::exception的库生成swig接口时出错
- 什么是 std::exception::what() 以及为什么要使用它?
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 链表"exception thrown"
- 为什么程序员同时使用 std::bad_alloc 和 std::exception.是否 std::例外 仅是不够的
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- C++ broken_promise exception
- 请参阅在 Visual Studio 2019 中捕获 std::exception 时对函数模板实例化消息的引用
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- QVTKWidget SetRenderWindow() with PCLVisualizer Exception