I wonder how a compiler treats lambda functions as opposed to regular functions. Even excluding the capture-list, as I think it's called, it seems to behave slightly differently.
For example, as used in my last post, Trying to pass a constexpr lambda and use it to explicitly specify returning type, I used a constexpr lambda and passed it as a regular function parameter. I quote a part of the answer.
Parameters to constexpr functions are not themselves constexpr objects - so you cannot use them in constant expressions.
template <typename Lambda_T>
constexpr static auto foo(Lambda_T l) {
return std::array<event, (l())>{};
}
// Compiles with GCC (C++17), though ill-formed (according to the answer of my last post)
Though, what catches my eye is that this does compile passing a constexpr lambda, but does not compile passing a constexpr regular (global) function. What causes this difference?
And are there other differences of behaviour of the compiler between regular functions and lambda-functions?
Edit: Example of Lambda-implementation
foo([](){ return 4; }); // C++17 Lambda's are implicitly constexpr
The lambda is basically a wrapper for the value in this case.
Edit: Global function
Whenever a global function is passed, the compiler will complain - as opposed to using a lambda - that this function, regardless of whether it is defined constexpr or not, cannot be used in a constant condition:
prog.cc:8:20: error: 'l' is not a constant expression
l()byfptr()wherefptris a function pointer initialized by a constant expression. The only difference I see, is that when called with a function argument, the function-to-pointer conversion applied to the argument to initialize the parameter may not be assumed to be a constant expression. But I suspect in c++20 it should be assumed to be a constant initialization and in c++17 it is even more obscure.