Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can a lambda passed as an argument be used in a constant expression?

Why does this code compile?

template<typename Callable>
int foo(Callable callable)
{
     static_assert(callable());
      return 0;
}

static const auto r = foo([] { return true; });

Compiler Explorer example

Shouldn't it be illegal to use a function parameter in a constant expression (the static_assert)?

It's disallowed for structural types, but it seems OK for lambdas as soon as they are passed by value. All of gcc, clang, and msvc accept it, so it might be legal somehow. I just can't find any reference why it's valid.

like image 867
Teskann Avatar asked Jan 25 '26 15:01

Teskann


1 Answers

While the variable is not a constant and not usable itself in a constant expression, members of the variable can be constant expressions. In this case the operator() of the lambda object is marked as constexpr, and it doesn't depend on the lambda object, so it can be used even though the object isn't.

We can get a little more of a simplified example with

int main()
{
    std::array<int, 4> nums{1, 3, 5, 7};

    static_assert(nums.size() == 4);
}

Here nums is not a constant, but size() always is as it's marked constexpr, and it just returns N, so it is still usable.

like image 149
NathanOliver Avatar answered Jan 28 '26 04:01

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!