Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if constexpr in a recursive generic lambda: different compiler behavior

The following code compiles successfully with g++ 7.3.0 and fails to compile with clang++ 6.0.0 (compilation flags are -std=c++17 -Wall -Wextra -Werror -pedantic-errors):

auto foo = [](auto, auto... tail) {
    if constexpr (sizeof...(tail) > 0)
    {
        return foo(tail...);
    }
    else
    {
        return 42;
    }
};

int main()
{
}

clang++ compilation error message:

error: variable 'foo' declared with deduced type 'auto' cannot appear in its own initializer

return foo(tail...);

What behavior is standard compliant in this case?

like image 533
Constructor Avatar asked May 03 '18 13:05

Constructor


1 Answers

Clang is right to reject this according to [dcl.spec.auto]/10, as of C++17.

If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed.

The type of foo is needed to resolve the recursive call (find operator(), etc). It's needed to determine the closure type. Since the closure type is being deduced here... you see where it goes.

GCC may prove it's not always impossible to get around it, but in general the standard prohibits it.

like image 68
StoryTeller - Unslander Monica Avatar answered Nov 12 '22 05:11

StoryTeller - Unslander Monica