Search code examples
c++lambdalanguage-lawyerstandardsfinal

Is inheritability of lambdas guaranteed by the standard?


In the C++ standard, closure types are defined as follows:

[expr.prim.lambda.closure] The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type, whose properties are described below. [...]

The standard does not seem to define whether or not the unnamed non-union class type is final. Would a compiler implementing lambdas as final classes be standard compliant, or do we have the guarantee that one can inherit from lambdas?

The question is not whether it is useful or not to inherit from lambdas: it's a given that it is useful. The question is whether the standard provides this guarantee.


Solution

  • Yes, the closure type must not be final. At least that's my interpretation.

    §8.1.5.1 Closure types [expr.prim.lambda.closure]

    An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:

    • ... [does not apply]

    The standard then doesn't describe the closure type as being final. Making it final would alter the observable behavior ergo the closure type must not be final.

    Regarding the observable behavior. Consider this:

    auto l = []{};
    return std::is_final_v<decltype(l)>;
    

    Making the closure type final would clearly modify the observable behavior of a valid program.


    As to a use case, it can actually be a very useful feature:

    template <class... Fs> struct Overload : Fs ...
    {
        using Fs::operator()...;
    };
    
    template <class... Fs> Overload(Fs...) -> Overload<Fs...>;
    
    auto test()
    {
        Overload f = {[] (int a) { return a * 100; },
                      [] (int a, int b) { return a + b;}};
    
        return f(1) + f(2, 3); // 105
    }
    

    See it in action on godbolt


    Thanks to hvd and rakete1111 for the discussions and feedback in the comments.