我发现一个问题,我猜是由于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) 返回的错误是:
错误:未在此范围内声明'f'
此外,请注意GCC compiles (2)如果按照以下方式进行修改:
l.remove_if([](const auto &t) { return t.func == &S<U>::f<int>; }); // (2)
据我所知,在这种情况下,使用const auto &
代替const T &
不应改变行为。
这是GCC的错误吗?
答案 0 :(得分:8)
每 [expr.prim.lambda] :
8 - [...] [For]名称查找(3.4)[...]复合语句在lambda表达式的上下文中被考虑。 [...]
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中的一个错误。