c++ - 有没有一种理想的方法可以避免这种使用 Naked New 的情况?

标签 c++ opencl c++20

在我的应用程序中,我需要设置回调,其唯一职责是更新与单独对象中已完成事件关联的状态,以便稍后可以查询。但是,由于 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) ,对我来说这似乎是某种反模式:使用裸体 newdelete与智能指针结合使用。

但是问题在于,由于回调必须是函数指针,所以我的 lambda 表达式无法复制或引用其他对象,而这是获取 shared_state 的唯一方法。 lambda 内部的对象将其指针传入;再说一次,因为我不能保证它的生命周期没有过期,所以我需要以指向 weak_ptr 的指针的形式获取它。这样当(且仅当)对象仍然存在时才可以对其进行操作。

最终,我的问题是:是否有一种理想的方式来传递 shared_state进入这个回调,其中

  1. 我可以检查以确保该对象仍然存在,同时
  2. 还消除了我对裸体的使用 newdelete来电?

最佳答案

在 lambda 中,只需使用 unique_ptr 即可实现明显的改进:

auto callback = [](cl_event event, cl_int, void* ptr) {
    std::unique_ptr<std::weak_ptr<render_future::shared_state>> ptr_ptr{ static_cast<std::weak_ptr<render_future::shared_state>*>(ptr)};
    if(auto shared_ptr = ptr_ptr->lock()) {
        std::lock_guard lock{ shared_state->mutex };
        shared_state->event_state[event] = true;
    }
}

在事物的创造方面,您可以使用 std::unique_ptr<>::release() .

auto ptr = std::make_unique<std::weak_ptr<render_future::shared_state>>(future.state);

event.setCallback(CL_COMPLETE, callback, ptr.release());

但是由于您正在使用无捕获 lambda 调用 C 函数,因此这里并不需要防止意外的异常,因此这是否比您当前正在做的事情有真正的改进是有争议的。

关于c++ - 有没有一种理想的方法可以避免这种使用 Naked New 的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61648829/

相关文章:

c++ - 在 C++11 中,是否可以将模板函数包装在 std::function 中?

c++ - QT 应用程序中显示为问号的阿拉伯文本

c - OpenCL 中的快速实现二进制求幂实现

c++ - 默认相等运算符是否有任何 C++20 功能测试?

c++ - 在 GoogleMock 中实现 WillN?

c++ - mingw g++ vector<T>::插入错误

c++ - 图像如何在 opencl 内核中工作?

java - 使用 OpenCl 与 java 的异构计算

c++ - C++20 中的协程是什么?

带有非类型模板参数的 C++20 lambda