Lambda functions as base classes

前端 未结 2 838
[愿得一人]
[愿得一人] 2020-12-02 09:23

Playing around with Lambdas I found an interesting behaviour that I do not fully understand.

Supose I have a struct Overload that derives from 2 templat

2条回答
  •  醉梦人生
    2020-12-02 09:39

    A lambda generates a functor class.

    Indeed, you can derive from lambdas and have polymorphic lambdas!

    #include 
    #include 
    
    int main()
    {
        auto overload = make_overload(
            [](int i)          { return '[' + std::to_string(i) + ']'; },
            [](std::string s)  { return '[' + s + ']'; },
            []                 { return "[void]"; }
            );
    
        std::cout << overload(42)              << "\n";
        std::cout << overload("yay for c++11") << "\n";
        std::cout << overload()                << "\n";
    }
    

    Prints

    [42]
    [yay for c++11]
    [void]
    

    How?

    template 
       Overload make_overload(Fs&&... fs)
    {
        return { std::forward(fs)... };
    }
    

    Of course... this still hides the magic. It is the Overload class that 'magically' derives from all the lambdas and exposes the corresponding operator():

    #include 
    
    template  struct Overload;
    
    template  struct Overload {
        Overload(F&& f) : _f(std::forward(f)) { }
    
        template 
        auto operator()(Args&&... args) const 
        -> decltype(std::declval()(std::forward(args)...)) {
            return _f(std::forward(args)...);
        }
    
      private:
        F _f;
    };
    
    template 
       struct Overload : Overload, Overload
    {
        using Overload::operator();
        using Overload::operator();
    
        Overload(F&& f, Fs&&... fs) :  
            Overload(std::forward(f)),
            Overload(std::forward(fs)...)
        {
        }
    };
    
    template 
       Overload make_overload(Fs&&... fs)
    {
        return { std::forward(fs)... };
    }
    

    See it Live on Coliru

提交回复
热议问题