mutable 允许修改lambda成员变量
mutable
在 C++ 中,mutable 关键字可以用在不同的上下文中。在你提供的代码中,mutable 出现在 lambda 表达式中,它有以下两个主要用途:
- 允许修改捕获的变量: 当你在 lambda 表达式中捕获变量时(默认是按值捕获),这些捕获的变量在 lambda 内是不可修改的。使用
mutable关键字可以让你在 lambda 内部修改这些捕获的变量。 - 允许修改成员变量: 如果 lambda 表达式是一个类的成员函数的一部分,并且该成员函数本身是
const,那么mutable也可以让你在 lambda 内部修改类的成员变量。
在你的代码中,mutable 的作用主要是第一个用途,即允许在 lambda 表达式内部修改捕获的变量。具体来说,以下是代码中的部分:
Async(EAsyncExecution::TaskGraph, [=, func = std::move(func)]() mutable
{
// 构建缩略图文件路径
FString path = FString::Printf(TEXT("%s/%s"), *FGamePath::GetThumbnailDir(), *id);
TArray64<uint8> imgData; // 用于存储从文件中读取的图像数据
// 检查文件是否存在并将其内容加载到imgData数组中
if (!IsFileExists(path) || !FFileHelper::LoadFileToArray(imgData, *path))
{
func(nullptr); // 如果文件不存在或加载失败,调用回调函数并传递null指针
return;
}
// 在主线程上执行异步任务以创建纹理
AsyncTask(ENamedThreads::GameThread, [=, func = std::move(func)]() mutable
{
UTexture2D* texture = GetTextureFromByteArray(imgData); // 从字节数组创建纹理
if (texture != nullptr)
{
// 将纹理添加到LRU缓存中
TextureLRU->Add(id, texture);
// 可以选择性更新资源(已注释掉)
// texture->UpdateResource();
}
else {
// 如果纹理创建失败,删除文件
IFileManager::Get().Delete(*path);
}
// 调用回调函数并传递创建的纹理
func(texture);
});
});
在这个例子中,有两个地方使用了 mutable:
Async(EAsyncExecution::TaskGraph, [=, func = std::move(func)]() mutable
{
// ...
});
和
AsyncTask(ENamedThreads::GameThread, [=, func = std::move(func)]() mutable
{
// ...
});
为什么这里需要 mutable?
- 捕获的变量按值传递:在这段代码中,lambda 捕获变量是按值捕获的(使用
[=]),这意味着它们在 lambda 内部被视为const。如果我们需要在 lambda 内部修改这些捕获的变量,例如func,我们就需要使用mutable关键字来解除这种限制。 - 转移所有权:特别是对于
func = std::move(func),我们需要修改func以转移其所有权(使用std::move)。如果没有mutable,在按值捕获的情况下,func会被视为const,我们无法对其进行std::move操作。
通过在 lambda 表达式中使用 mutable,我们可以在 lambda 内部修改这些捕获的变量,从而实现所需的功能。

浙公网安备 33010602011771号