15

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?

3
  • 2
    i don't see how it can compile because foo isn't captured (and can't be captured) Commented May 3, 2018 at 13:35
  • 2
    @Tyker There is no need to capture global objects like foo in this example. Commented May 3, 2018 at 13:38
  • 5
    The 2017 paper p0839r0 proposes a change to the C++ grammar to allow a self-referential name in a lambda's declaration. Commented May 3, 2018 at 13:42

1 Answer 1

12

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.

Sign up to request clarification or add additional context in comments.

4 Comments

@Constructor - The rest of [dcl.spec.auto]/10 actually addresses that. I didn't bring it in because you didn't ask about it in your posted question.
@Constructor - And there's also [dcl.spec.auto]/8. It's different things, really. In a subtle way.
Thank you very much for your answer and references! It looks like a sad story in fact.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.