【发布时间】:2017-02-07 13:16:30
【问题描述】:
我发现了一个问题,我猜是由于 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 的 bug?
【问题讨论】:
-
我想知道编译器在什么范围内生成代表 generic lambda 的类:文件范围、类范围、函数范围(作为本地类,但不支持函数模板作为成员)?
-
来自here - 闭包类型在包含相应lambda表达式的最小块作用域、类作用域或命名空间作用域中声明。我会说
S<U>,这就是为什么我认为这是一个错误,它应该查看f的声明。 -
@Nawaz 也许this 更合适 - 本地 lambda 表达式的到达范围是一组封闭范围,包括最里面的封闭函数及其参数?
-
@skypjack 嗯,如果您删除外部模板 (
typename <class U>),它也会被编译... -
@W.F.是的,当然,我注意到了。最小的工作示例真的是 minimal 一个!我尽力了。 ;-)
标签: gcc lambda clang c++14 language-lawyer