Reputation: 50550
I found a problem that I guess is due to a bug in GCC.
Anyway, before opening an issue, I would like to be sure.
Consider the code below:
#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) as expected.
GCC v6.2 compiles (1), but it doesn't compile (2).
The returned error is:
error: 'f' was not declared in this scope
Moreover, note that GCC compiles (2) if it is modified as it follows:
l.remove_if([](const auto &t) { return t.func == &S<U>::f<int>; }); // (2)
As far as I know, using an const auto &
instead of const T &
should not alter the behavior in this case.
Is it a bug of GCC?
Upvotes: 12
Views: 308
Reputation: 157374
Per [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;
Hoisting the compound-statement to the context of the lambda-expression gives a clearly valid program:
template<int>
struct S {
template<int> static void f();
S() { f<0>; }
};
S<0> s;
So yes, this is a bug in gcc.
Upvotes: 8