Is a lambda expression a legal default (non-type template) argument?

Is a lambda expression a legal default (non-type template) argument and, if so, wouldn’t this imply that each instantiation using such a default argument instantiates a unique specialization?

Yes, it means that given your templated variable:

template<auto l = [](){}>
constexpr auto default_lambda = l;

every call to default_lambda will produce a new template instantiation by generating a new unique closure type and thus provides a new way to capture a metaprogramming state.

Thus, every expressions that use default_lambda have to be reevaluated. If the state of the compiler changed since the last instantiation and if we used it in a dependent expression (ex: check that a type is defined) then the result of the expression might change.
For example:

struct X; // not defined

template <typename T, auto = default_lambda<>>
consteval bool is_defined() {
    if constexpr (requires { T{}; }) {
        return true;
    } else {
        return false;
    }
}

static_assert(is_defined<X>() == false);

struct X {};
static_assert(is_defined<X>() == true);

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)