具有空捕获列表的Lambda仍然能够从全局范围捕获对象

Lambda with empty capture list still able to capture objects from global scope?

本文关键字:范围捕 全局 围捕 对象 列表 Lambda      更新时间:2023-10-16

我有几个全局静态对象。别介意这些是Qt类,这与问题无关。

static const QStringList JpegFileExtensions = QString::fromLatin1(jpegExtensions).split(" ");
static const QStringList TiffFileExtensions = QString::fromLatin1(tiffExtensions).split(" ");
static const QStringList RawFileExtensions = QString::fromLatin1(rawExtensions).split(" ");
static const QStringList PngFileExtensions = QString::fromLatin1(pngExtensions).split(" ");

现在,我有另一个静态对象,它由一些函数初始化,该函数接受以前的对象并计算结果:

inline QString GetAllSupportedExtensions() {
   QStringList extensions = QStringList() << JpegFileExtensions << TiffFileExtensions << RawFileExtensions << PngFileExtensions;
   for (QString& item: extensions)
        item.remove("*.");
   return extensions;
}
static const QString AllSupportedExtensions = GetAllSupportedExtensions();

但由于这个GetAllSupportedExtensions函数在其他地方没有使用,我想去掉它,这样它就不会扰乱命名空间。很自然,我想到了使用lambda,它是一个匿名函数:

static const QStringList AllSupportedExtensions = []() -> QStringList {
    QStringList list = QStringList() << JpegFileExtensions << TiffFileExtensions << RawFileExtensions << PngFileExtensions;
    for (QString& item: list)
        item.remove("*.");
    return list;
} ();

请注意空的捕获列表和空的参数列表。它在Windows(msvc-2013)和OS X(clang-7001.81)上编译和工作?它是否符合标准,是否应该使用空的捕获列表进行编译?

lambda没有捕获任何内容。您在函数中使用全局变量。lambda的函数体是放在表示lambda的未命名类的operator()中的内容。您可以使用任何函数来执行此操作。

你可以在这个简单的例子中看到这一点

int i = 10;
class Foo
{
public:
    void operator()() { i = 20; }
};
int main(){
    Foo f;
    f();
    std::cout << i;
}

实时示例