【发布时间】:2020-05-07 02:27:51
【问题描述】:
在我的应用程序中,我需要设置回调,其唯一职责是在单独的对象中更新与已完成事件关联的状态,以便以后可以对其进行查询。但是,由于 API 的设计方式,我不能保证在事件完成时其他对象仍然拥有,因此我需要存储指向该对象的指针,并且因为回调 API 是基于 C 的,我最终存储了一个指向智能指针的原始指针,这是我见过的最丑陋的代码*。
* 反正最近几个小时...
这就是我写来完成这个的:
event.setCallback(CL_COMPLETE, [](cl_event event, cl_int, void* ptr) {
auto ptr_ptr = static_cast<std::weak_ptr<render_future::shared_state>*>(ptr);
if(auto shared_ptr = ptr_ptr->lock()) {
auto & shared_state = *shared_ptr;
std::lock_guard lock{ shared_state.mutex };
shared_state.event_state[event] = true;
}
delete ptr_ptr;
}, new std::weak_ptr<render_future::shared_state>(future.state));
我特别反对我自己使用new std::weak_ptr<render_future::shared_state>(future.state),在我看来这似乎是某种反模式:将裸new 和delete 与智能指针结合使用。
然而,问题在于,因为回调必须是函数指针,我的 lambda 表达式无法复制或引用其他对象,而在 lambda 中获取 shared_state 对象的唯一方法是将其指针传入;再一次,因为我不能保证它的生命周期没有过期,我需要以指向 weak_ptr 的指针的形式获取它,以便在(且仅当)对象仍然存在时可以对其进行操作。
所以最终,我的问题是:有没有一种理想的方式将shared_state 传递到这个回调中
- 我可以检查以确保对象仍然存在,而
- 还消除了我对裸
new和delete调用的使用?
【问题讨论】: