Lambda 标识符是如何捕获的?
How are Lambda Identifiers Captured?
我已经发布了 this answer,其中包含代码:
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); };
}
我在想 first
、second
和 third
真的可以像这样用作 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。没有地方可以在 lambda 捕获列表中放置 cv 限定符。你可以看看 relevant grammar:
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 polygon
是 const
,所以在你的情况下,first
、second
和 third
如果您在捕获列表中通过引用捕获它们,实际上将是 const
!但如果不是,则不会,原因如上所述。
我已经发布了 this answer,其中包含代码:
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); };
}
我在想 first
、second
和 third
真的可以像这样用作 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。没有地方可以在 lambda 捕获列表中放置 cv 限定符。你可以看看 relevant grammar:
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 polygon
是 const
,所以在你的情况下,first
、second
和 third
如果您在捕获列表中通过引用捕获它们,实际上将是 const
!但如果不是,则不会,原因如上所述。