GCCのバグが原因だと思う問題が見つかりました。
とにかく、問題を開く前に、私は確信しています。予想通りstd :: list :: remove_ifが一般的なラムダと組み合わされて狂ってしまう
#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();
}
打ち鳴らすのV3.9 compiles both (1) and (2):
は、以下のコードを検討してください。
GCCv6.2 compiles (1)ですが、doesn't compile (2)です。
返されるエラーは、次のとおり
l.remove_if([](const auto &t) { return t.func == &S<U>::f<int>; }); // (2)
を私の知る限り、変えるべきではないconst auto &
代わりconst T &
の使用:
error: 'f' was not declared in this scope
また、それは次のようにGCC compiles (2)は、それが変更された場合注意しますこの場合の動作
GCCのバグですか?
コンパイラが* generic * lambda:file-scope、class-scope、function-scopeを表すクラスを生成するのは不思議です(local-classとして* )? – Nawaz
ここから(http://eel.is/c++draft/expr.prim.lambda##) - _クロージャタイプは、対応するラムダを含む最小のブロックスコープ、クラススコープ、または名前空間スコープで宣言されています-expression_。私は 'S 'と言うでしょう。だからこそバグだと思うし、 'f'の宣言をするべきです。 – skypjack
@Nawazおそらく[this](http://eel.is/c++draft/expr.prim.lambda#10)がさらに適切です - ローカルのラムダ式の到達範囲は、最大の囲みスコープのセットです最も内側の包囲関数とそのパラメータを含む。 – skypjack