如何捕获 Lambda 标识符

How are Lambda Identifiers Captured?

本文关键字:标识符 Lambda 何捕获      更新时间:2023-10-16

我已经发布了这个答案,其中包含代码:

template <typename T>
auto vertex_triangle(const size_t index, const vector<pair<T, T>>& polygon) {
    const auto& first = index == 0U ? polygon.back() : polygon[index - 1U];
    const auto& second = polygon[index];
    const auto& third = index == size(polygon) - 1U ? polygon.front() : polygon[index + 1U];
    return [&](auto& output){ output.push_back(first);
                              output.push_back(second);
                              output.push_back(third); };
}

我在想firstsecondthird真的可以用作lambda标识符,如下所示:

[first = index == 0U ? polygon.back() : polygon[index - 1U],
 second = polygon[index],
 third = index == size(polygon) - 1U ? polygon.front() : polygon[index + 1U]](auto& output){ output.push_back(first);
                                                                                             output.push_back(second);
                                                                                             output.push_back(third); };

但我只想通过不断的引用来捕捉。如果不在标识符中指定类型,我该怎么做?

你不能1.没有地方可以将 cv 限定符放在 lambda 捕获列表中。你可以看看相关的语法:

init-capture:
    identifier initializer
    & identifier initializer

也不能在捕获列表中指定类型(请参阅上面的语法)。

但是,您可以做的是通过在名称前放置一个&来捕获非常量引用:

[&first = index == 0U ? polygon.back() : polygon[index - 1U],
 &second = polygon[index],
 &third = index == size(polygon) - 1U ? polygon.front() : polygon[index + 1U]](auto& output){ output.push_back(first);
                                                                                             output.push_back(second);
                                                                                             output.push_back(third); };

或者只是坚持你的第一个片段,这也更具可读性。


1 polygonconst,所以在您的情况下,如果您在捕获列表中通过引用捕获它们,firstsecondthird实际上将被const!但如果不是,那么不,出于上述原因。