删除者的调用上下文
Deleter's calling context
与标准智能指针一起使用的 C++ Deleter 是否可以确定调用它的上下文?
假设释放我的资源可能会产生错误。
如果我的资源在堆栈展开期间被释放,我显然不希望我的 Deleter 在出现错误时抛出异常。但是如果使用reset()调用了Deleter,那么向我代码的用户报错就可以了。
struct MyDeleter
{
typedef ... pointer;
void operator ()(pointer p)
{
if (release_p_failed)
{
if (throwing_exception_is_ok)
throw ...;
else
hide_error_to_not_abort;
}
}
};
例子
{
std::unique_ptr<..., MyDeleter> p{ ..., MyDeleter };
// A:
p.reset(); // User intends to handle the error. Throwing exception is ok.
// B: Leave scope and do not throw an exception in case of an error.
}
不,unique_ptr
不提供任何方法来确定删除器的调用上下文。
在这种情况下,您需要提供单独的清理逻辑。
您可以使用std::uncaught_exception()
来区分正常销毁和堆栈展开。
如果您担心在堆栈展开期间抛出异常,您应该使用 std::uncaught_exception,例如
struct MyDeleter
{
typedef ... pointer;
void operator ()(pointer p)
{
if (release_p_failed)
{
if (!std::uncaught_exception()) // no stack unwinding in progress
throw ...;
else
hide_error_to_not_abort;
}
}
};
如果您需要从任何析构函数中抛出,这是使用的标准习惯用法。
当然,这不能区分是从std::unique_ptr::~std::unique_ptr
和std::unique_ptr::reset()
调用的。
请注意,从 C++17 开始,std::uncaught_exception
已被弃用并被 std::uncaught_exceptions
取代,返回当前未捕获异常的数量 'in the air'。
与标准智能指针一起使用的 C++ Deleter 是否可以确定调用它的上下文?
假设释放我的资源可能会产生错误。
如果我的资源在堆栈展开期间被释放,我显然不希望我的 Deleter 在出现错误时抛出异常。但是如果使用reset()调用了Deleter,那么向我代码的用户报错就可以了。
struct MyDeleter
{
typedef ... pointer;
void operator ()(pointer p)
{
if (release_p_failed)
{
if (throwing_exception_is_ok)
throw ...;
else
hide_error_to_not_abort;
}
}
};
例子
{
std::unique_ptr<..., MyDeleter> p{ ..., MyDeleter };
// A:
p.reset(); // User intends to handle the error. Throwing exception is ok.
// B: Leave scope and do not throw an exception in case of an error.
}
不,unique_ptr
不提供任何方法来确定删除器的调用上下文。
在这种情况下,您需要提供单独的清理逻辑。
您可以使用std::uncaught_exception()
来区分正常销毁和堆栈展开。
如果您担心在堆栈展开期间抛出异常,您应该使用 std::uncaught_exception,例如
struct MyDeleter
{
typedef ... pointer;
void operator ()(pointer p)
{
if (release_p_failed)
{
if (!std::uncaught_exception()) // no stack unwinding in progress
throw ...;
else
hide_error_to_not_abort;
}
}
};
如果您需要从任何析构函数中抛出,这是使用的标准习惯用法。
当然,这不能区分是从std::unique_ptr::~std::unique_ptr
和std::unique_ptr::reset()
调用的。
请注意,从 C++17 开始,std::uncaught_exception
已被弃用并被 std::uncaught_exceptions
取代,返回当前未捕获异常的数量 'in the air'。