Lambda捕获shared_ptr成员

Kai*_*aan 8 c++ lambda memory-management smart-pointers c++11

我有一个类OpenGLRenderer具有类成员mMemoryAllocator这是一个std::shared_ptr<MemoryAllocator>.我将内存分配器保留在shared_ptr中的原因是因为即使shared_ptr<Texture>返回的下面的内容超过了它的创建者OpenGLRenderer,MemoryAllocator如果我按值捕获它,实例仍然有效,因为它会增加引用计数:

std::shared_ptr<Texture> OpenGLRenderer::CreateTexture(TextureType textureType, const std::vector<uint8_t>& textureData, uint32_t textureWidth, uint32_t textureHeight, TextureFormat textureFormat)
{
    return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
                                    textureData, textureWidth, textureHeight,
                                    textureFormat, textureType, mLogger), 
                                    [=](Texture* texture) { 
                                        mMemoryAllocator
                                         ->DeallocateObject<Texture>(texture); 
                                    });
}
Run Code Online (Sandbox Code Playgroud)

......但是,它不起作用.如果OpenGLRenderer超出范围之前std::shared_ptr<Texture>,std::shared_ptr<MemoryAllocator>则会变得损坏,因此lambda表达式变得疯狂.我做错了什么?

Dav*_*eas 11

在这种情况下的问题是lambda不捕获对象的成员,而是捕获this指针.一个简单的解决方法是创建一个局部变量并绑定:

std::shared_ptr<Texture> 
OpenGLRenderer::CreateTexture(TextureType textureType, 
                              const std::vector<uint8_t>& textureData, 
                              uint32_t textureWidth, uint32_t textureHeight, 
                              TextureFormat textureFormat)

{
    std::shared_ptr<AllocatorType> allocator = mMemoryAllocator;
    return std::shared_ptr<Texture>(mMemoryAllocator->AllocateObject<Texture>(
                                    textureData, textureWidth, textureHeight,
                                    textureFormat, textureType, mLogger), 
                                    [=](Texture* texture) { 
                                        allocator
                                         ->DeallocateObject<Texture>(texture); 
                                    });
}
Run Code Online (Sandbox Code Playgroud)

  • @KaiserJohaan:简而言之,你问题中的lambda被处理为`this-> mMemoryAllocator-> DeallocateObject <Texture>(texture);`,使用的本地*对象*是`this`,和` [=]`会抓住那个.不是你使用的对象的成员,而是`this`指针.你是靠价值捕捉,而不是正确的东西 (4认同)