【问题标题】:Lambda capture shared_ptr memberLambda 捕获 shared_ptr 成员
【发布时间】:2013-10-31 22:38:40
【问题描述】:

我有一个班级OpenGLRenderer,其中有一个班级成员mMemoryAllocator,即std::shared_ptr<MemoryAllocator>。我将内存分配器保留在 shared_ptr 中的原因是,即使下面返回的shared_ptr<Texture> 比它的创建者OpenGLRenderer 寿命更长,如果我按值捕获它,MemoryAllocator 实例仍然有效,因为它会增加 ref计数:

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); 
                                    });
}

...但是,它不起作用。如果OpenGLRendererstd::shared_ptr&lt;Texture&gt; 之前超出范围,std::shared_ptr&lt;MemoryAllocator&gt; 就会损坏,因此 lambda 表达式会变得疯狂。我做错了什么?

【问题讨论】:

  • 提问时,尽可能让其他人轻松阅读您的代码。

标签: c++ memory-management c++11 lambda smart-pointers


【解决方案1】:

这种情况下的问题是 lambdas 不捕获对象的成员,而是捕获 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); 
                                    });
}

【讨论】:

  • 为什么 '=' 不能帮助捕获?
  • @KaiserJohaan:长话短说,您问题中的 lambda 被处理为 this-&gt;mMemoryAllocator-&gt;DeallocateObject&lt;Texture&gt;(texture);,使用的本地 objectthis,而 @ 987654325@ 将捕捉到这一点。不是您使用的对象的成员,而是this 指针。您是按价值捕获,而不是正确的东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
相关资源
最近更新 更多