问题
Consider the following code:
int main() {
auto l = [](auto){};
void(*p)(int) = l;
}
It works just fine both with GCC and clang.
Let's consider the following slightly modified version:
int main() {
auto l = [](auto...){};
void(*p)(int) = l;
}
In this case, clang still accepts it while GCC rejects it.
Is there any reason for which this code should be rejected or is it a bug of the compiler?
I'm going to open an issue, but I'd like to know if there exists any proposal that could have been implemented by one of them and not by the other one.
回答1:
This is a known GCC parsing bug (64095, 68071): [](auto...){}
is being mistakenly parsed like [](auto, ...) {}
rather than [](auto...x){}
; the ellipsis is being parsed as C-style varargs rather than declaring a parameter pack (in language-lawyer terms, it's being parsed as part of the parameter-declaration-clause rather than the abstract-declarator, in violation of [dcl.fct]/17).
It should go without saying that [](auto, ...){}
isn't convertible to void (*)(int)
.
The workaround is to give the pack a name; if you do, you'll see that the conversion compiles successfully.
来源:https://stackoverflow.com/questions/41317113/should-non-capturing-generic-lambdas-decay-to-function-pointers