You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不销毁对象的前提下将对象从一个vector移至另一个vector?

如何在非渲染线程将GPU资源对象从vector中间移至另一个vector末尾?

我有一个存储GPU资源对象的vector,这些对象只能在特定渲染线程中安全创建或销毁,但现在需要在非渲染线程里把它们从一个vector的中间位置移到另一个vector的末尾。

为了安全,我已经删除了该类的拷贝构造、拷贝赋值和移动赋值运算符,只保留了移动构造函数。请问有没有办法实现这个移动操作,且不会销毁任何对象?

相关代码如下:

class MappedBuffer {
public:
    MappedBuffer(GLuint name, char * mapping) : m_name(name), m_mapping(mapping) {
        assert(std::this_thread::get_id() == RENDER_THREAD_ID);
    };
    MappedBuffer(MappedBuffer && other) : m_name(other.m_name), m_mapping(other.m_mapping) {
        other.m_name = 0;
        other.m_mapping = 0;
    }
    MappedBuffer(const MappedBuffer & other) =delete;
    MappedBuffer & operator=(MappedBuffer && other) =delete;
    MappedBuffer & operator=(const MappedBuffer & other) =delete;
    ~MappedBuffer() {
        assert(m_name == 0 || std::this_thread::get_id() == RENDER_THREAD_ID);
        if (m_name) {
            gl::buffer::unmap(m_name);
            gl::buffer::dealloc(m_name);
        }
    }

private:
    char * m_mapping    {0}; // 直接指向GPU内存
    GLuint m_name       {0};
};


// 非渲染线程
int f(size_t srcIndex, std::vector<MappedBuffer> & src, std::vector<MappedBuffer> & dest) {

    // 如何实现类似下面的操作,但不销毁任何对象?
    // dest.push_back(src.begin() + srcIndex);
    // dest.erase(src.begin() + srcIndex);
    
}

解决方案

可以通过std::move结合vector的emplace_back和erase方法实现,核心是利用移动构造函数转移资源所有权,同时让原位置对象处于空状态(不会触发GPU资源销毁)。

修改后的f函数代码如下:

// 非渲染线程
int f(size_t srcIndex, std::vector<MappedBuffer> & src, std::vector<MappedBuffer> & dest) {
    // 边界检查,避免越界访问
    if (srcIndex >= src.size()) {
        return -1; // 返回错误码表示操作失败
    }

    // 用std::move将原对象转为右值,触发移动构造,转移资源所有权
    dest.emplace_back(std::move(src[srcIndex]));
    // 擦除原位置的空对象,此时对象m_name为0,析构不会执行GPU资源释放
    src.erase(src.begin() + srcIndex);
    
    return 0; // 操作成功返回0
}

原理说明

  • std::move(src[srcIndex])将原对象转换为右值引用,调用MappedBuffer的移动构造函数,把GPU资源的所有权转移到dest的新对象中,同时将原对象的m_name和m_mapping置为0。
  • 原位置的对象此时处于“空”状态,调用src.erase触发析构时,因为m_name为0,析构函数里的GPU资源释放逻辑不会执行,完全符合线程安全要求。
  • 整个过程仅转移资源所有权,没有拷贝、创建或销毁GPU资源,完全满足你的需求。

内容的提问来源于stack exchange,提问作者Anne Quinn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:35:18