Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should non-capturing generic lambdas decay to function pointers?

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.

like image 892
skypjack Avatar asked Dec 24 '16 21:12

skypjack


People also ask

How do you convert lambda to a function?

To create a lambda function first write keyword lambda followed by one of more arguments separated by comma ( , ), followed by colon a ( : ), followed by a single line expression. Here we are using two arguments x and y , expression after colon is the body of the lambda function.

How do you declare a function pointer in C++?

We declare the function pointer, i.e., void (*ptr)(char*). The statement ptr=printname means that we are assigning the address of printname() function to ptr. Now, we can call the printname() function by using the statement ptr(s).

What is the type of a lambda?

A type lambda lets one express a higher-kinded type directly, without a type definition. For instance, the type above defines a binary type constructor, which maps arguments X and Y to Map[Y, X] . Type parameters of type lambdas can have bounds, but they cannot carry + or - variance annotations.


1 Answers

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.

like image 197
T.C. Avatar answered Sep 23 '22 16:09

T.C.