Search code examples
c++lambdalanguage-lawyerc++20requires-expression

Capture of a local parameter in requires expression


A requires-expression similarly to a function can introduce local parameters using a parameter list. And lambda expressions defined at block scope may have captures without initializers. Is it allowed to capture local parameters of requires-expression?

Consider the example:

template<typename T>
concept C = requires( T t ) { 
    [t]{ [t]{}; };
};

which is accepted by both GCC and MSVC. And only Clang complains (demo: https://gcc.godbolt.org/z/o17hWGabG) here:

error: constraint variable 't' cannot be used in an evaluated context

As far as I understand [t]{ [t]{}; }; is a simple requirement, where the expression is an unevaluated operand; only language correctness is checked.

What is the expected behavior of a compiler here?


Solution

  • From expr.prim.req.general#2 (my emphasis):

    A requires-expression is a prvalue of type bool whose value is described below. Expressions appearing within a requirement-body are unevaluated operands.

    where "requirement-body" refers to the { … } part.

    So Clang is complaining incorrectly, I believe.

    Furthermore, this discussion on llvm-project seems to support my understanding. I suspect you're are the one who reported it there too, by the way.


    user17732522's point below is that