我发现了一个问题,我猜是由于 GCC 中的一个错误。
无论如何,在打开问题之前,我想确定一下。
考虑下面的代码:
#include<algorithm>
#include<list>
template<typename U>
struct S {
using FT = void(*)();
struct T { FT func; };
template<typename>
static void f() { }
std::list<T> l{ { &f<int> }, { &f<char> } };
void run() {
l.remove_if([](const T &t) { return t.func == &f<int>; }); // (1)
l.remove_if([](const auto &t) { return t.func == &f<int>; }); // (2)
}
};
int main() {
S<void> s;
s.run();
}
clang v3.9 compiles both (1) and (2)正如预期的那样。
GCC v6.2 compiles (1) ,但它doesn't compile (2) .
返回的错误是:
error: 'f' was not declared in this scope
此外,请注意 GCC compiles (2)如果修改如下:
l.remove_if([](const auto &t) { return t.func == &S<U>::f<int>; }); // (2)
据我所知,使用
const auto &
而不是 const T &
在这种情况下不应改变行为。这是GCC的错误吗?
最佳答案
每 [expr.prim.lambda] :
8 - [...] [For] purposes of name lookup (3.4) [...] the compound-statement is considered in the context of the lambda-expression. [...]
MCVE :
template<int>
struct S {
template<int> static void f();
S() { void(*g)(char) = [](auto) { f<0>; }; }
};
S<0> s;
将复合语句提升到 lambda 表达式的上下文给出了一个明确有效的程序:
template<int>
struct S {
template<int> static void f();
S() { f<0>; }
};
S<0> s;
所以是的,这是 gcc 中的一个错误。
关于gcc - 如果与通用 lambda 结合使用 std::list::remove_if 会变得疯狂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39766467/