首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用boost::python::句柄作为临时句柄?

使用boost::python::句柄作为临时句柄?
EN

Stack Overflow用户
提问于 2015-09-17 13:48:19
回答 1查看 45关注 0票数 0

在自定义转换器中,我正在检查序列项是否为某种类型。到目前为止,我已经完成了这段代码(简化)

代码语言:javascript
复制
namespace bp=boost::python;
/* ... */
static void* convertible(PyObject* seq_ptr){
    if(!PySequence_Check(seq_ptr)) return 0;
    for(int i=0; i<PySequence_Size(seq_ptr); i++) 
        if(!bp::extract<double>(PySequence_GetItem(seq_ptr,i)).check()) return 0;
    /* ... */
}
/* ... */

但这是内存泄漏,因为GetItem正在返回一个新的引用。所以要么我可以在循环中做这样的事情:

代码语言:javascript
复制
PyObject* it=PySequence_GetItem(seq_ptr,i);
bool ok(bp::extract<double>(it).check();
Py_DECREF(it); // will delete the object which had been newly created
if(!ok) return 0;

但这是相当笨拙的;我可以做一个独立的函数来实现这一点,但这正是我回忆起bp::handle实现引用计数机制的地方;所以,类似这样的事情可能会做到:

代码语言:javascript
复制
if(!bp::extract<double>(bp::handle<>(PySequence_GetItem(seq_ptr,i))).check()) return 0;

但是此页提到使用句柄作为临时人员是不可取的。为什么?在实际调用.check()之前,可以销毁该对象吗?还有其他优雅的方式来写这个吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-17 15:59:24

在调用.check()之前不会销毁该对象,并且在发布的上下文中是安全的。

不使用临时人员的建议是由于对论点和例外安全的评估顺序不明确。如果只有一个可以计算参数的顺序,例如在您的示例中,那么它是安全的。例如,考虑函数bad(),它总是抛出异常:

代码语言:javascript
复制
f(boost::python::handle<>(PySequence_GetItem(...)), bad());

如果bad()PySequence_GetItem(...)boost::python::handle<>(...)之间得到评估,那么当堆栈在构建boost::python::handle<>之前开始展开时,新的引用将被泄露。另一方面,在使用非临时的情况下,PySequence_GetItem()boost::python::handle<>()之间没有可能抛出一些东西,因此在出现异常时,以下内容是安全的:

代码语言:javascript
复制
boost::python::handle<> item_handle(PySequence_GetItem(...));
f(item_handle, bad());

想了解更多细节,请考虑阅读Herb的GotW #56:异常安全函数调用

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32631982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档