clang vs gcc:可变参数lambda捕获 [英] clang vs gcc: variadic lambda captures
问题描述
我试图在内部lambda中捕获一个可变参数的lambda参数,并在其中使用它. 例如,请考虑以下代码:
I am trying to capture a variadic lambda argument inside a inner lambda and use it there. As an example, consider this code:
int main () {
auto first = [&] (auto&&... one) {
auto second = [&] (auto&&... two) {
return ((one * two) + ...);
};
return second(one...);
};
return first(5);
}
这适用于gcc9,但不适用于clang8( https://godbolt.org/z/i2K9cK ).
This works with gcc9 but fails with clang8 (https://godbolt.org/z/i2K9cK).
使代码编译的一种方法是显式捕获[&one...]
,但是我想知道这是否是clang中的错误.
A way to make the code compile is to explicitly capture [&one...]
, but i was wondering whether this is a bug in clang.
也很有趣:将return语句更改为直接扩展one
的内容(与two
组合在一起),然后再次编译:
return (((one * ...) * two) + ...);
Also interesting: Changing the return statement to something where one
is directly expanded (before combining with two
), this compiles again:
return (((one * ...) * two) + ...);
我发现了与此相关的帖子,但是声明的错误似乎已在clang8中修复.
I have found this related post, but the bug declared there seems to be fixed in clang8.
推荐答案
This is a bug in Clang. It has been reported. Per comment:
已在r362358中修复.
Fixed in r362358.
(附带说明:Clang似乎在捕获中通常难以扩展包.让我们推出为通用lambda first
生成的闭包类型的自己版本:
(Side note: Clang seems to have difficulty with pack-expansions in captures in general. Let's roll out our own version of the closure type generated for the generic lambda first
:
struct __closure_first {
template <typename... Args>
auto operator()(Args&&... one) const
{
auto second = [&] (auto&&... two) {
return ((one * two) + ...);
};
return second(one...);
}
};
很明显,这不是真正的闭包类型,并且非闭包本地类不能具有成员函数模板.将其放到全球范围内, GCC仍然有效和
Clearly, this is not a real closure type, and non-closure local classes cannot have member function templates. Putting this in the global scope, GCC still works and Clang still fails.)
这篇关于clang vs gcc:可变参数lambda捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!