рдПрдХ рдбреЗрдХреЛрд░реЗрдЯрд░ - рд╕реА ++, рдкрд╛рдпрдерди рдФрд░ рдЗрд╕рдХреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдХреИрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рднрд╛рдЧ 1

рд▓реЗрдЦреЛрдВ рдХреА рдпрд╣ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕реА ++ рдореЗрдВ рдПрдХ рдбреЗрдХреЛрд░реЗрдЯрд░ рдмрдирд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдкрд┐рдд рд╣реЛрдЧреА , рдкрд╛рдпрдерди рдореЗрдВ рдЙрдирдХреЗ рдХрд╛рдо рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ, рдФрд░ рдЕрдкрдиреА рд╕реНрд╡рдпрдВ рдХреА рд╕рдВрдХрд▓рд┐рдд рднрд╛рд╖рд╛ рдореЗрдВ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрд▓реЛрдЬрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП - рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА рдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдФрд░ рдЖрдзреБрдирд┐рдХреАрдХрд░рдгред



рдЕрд╕реНрд╡реАрдХрд░рдг
, Python тАФ . Python , (). - ( ), - ( , ..), Python ┬л┬╗ .

рд╕реА ++ рдореЗрдВ рдбреЗрдХреЛрд░реЗрдЯрд░


рдпрд╣ рд╕рдм рдЗрд╕ рддрдереНрдп рд╕реЗ рд╢реБрд░реВ рд╣реБрдЖ рдХрд┐ рдореЗрд░реЗ рджреЛрд╕реНрдд VoidDruid рдиреЗ рдПрдХ рдбрд┐рдкреНрд▓реЛрдорд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЫреЛрдЯрд╛ рд╕рдВрдХрд▓рдХ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛, рдЬрд┐рд╕рдХреА рдкреНрд░рдореБрдЦ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рд╣реИред рдкреВрд░реНрд╡-рд░рдХреНрд╖рд╛ рдХреЗ рджреМрд░рд╛рди рднреА, рдЬрдм рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдкрдиреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рднреА рд▓рд╛рднреЛрдВ рдХреЛ рд░реЗрдЦрд╛рдВрдХрд┐рдд рдХрд┐рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рдПрдПрд╕рдЯреА рдХреЛ рдмрджрд▓рдирд╛ рд╢рд╛рдорд┐рд▓ рдерд╛, рддреЛ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛: рдХреНрдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдорд╣рд╛рди рдФрд░ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕реА ++ рдореЗрдВ рдЗрди рд╕рдорд╛рди рд╕рдЬреНрдЬрд╛рдХрд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ рдФрд░ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЬрдЯрд┐рд▓ рд╢рдмреНрджреЛрдВ рдФрд░ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ? рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдореБрдЭреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рд░рд▓ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рдирд╣реАрдВ рдорд┐рд▓рд╛ (рд╡реИрд╕реЗ, рдореИрдВ рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЗрд╡рд▓ рд▓реЗрдЦ рднрд░ рдореЗрдВ рдЖрдпрд╛ рдерд╛) рдФрд░ рдлрд┐рд░ рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмреИрда рдЧрдпрд╛ред


рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореЗрд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд┐рд╡рд░рдг рдкрд░ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдереЛрдбрд╝рд╛ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рд╕реА ++ рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рдФрд░ рдХреНрд▓реЛрдЬрд░ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреЗ рдмреАрдЪ рдХреНрдпрд╛ рдЕрдВрддрд░ рд╣реИред рддреБрд░рдВрдд рдПрдХ рдЖрд░рдХреНрд╖рдг рдХрд░реЗрдВ рдХрд┐ рдпрджрд┐ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдирдХ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рд╣реИ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ C ++ 20ред рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рд▓реИрдореНрдмреНрдбрд╛ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВ, рдФрд░ рдХреНрд▓реЛрдЬрд╝рд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╣реИрдВ рдЬреЛ рдЕрдкрдиреЗ рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, C ++ 11 рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░, рдПрдХ рд▓рдВрдмреЛрджрд░ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

int main() 
{
    [] (int a) 
    {
        std::cout << a << std::endl;
    }(10);
}

рдпрд╛ рдХрд┐рд╕реА рд╡реИрд░рд┐рдПрдмрд▓ рдкрд░ рдЙрд╕рдХрд╛ рдорд╛рди рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ рдФрд░ рдмрд╛рдж рдореЗрдВ рдХреЙрд▓ рдХрд░реЗрдВред

int main() 
{
    auto lambda = [] (int a) 
    {
        std::cout << a << std::endl;
    };
    lambda(10);
}

рд▓реЗрдХрд┐рди рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд▓реИрдореНрдмрдбрд╛ рдХреНрдпрд╛ рд╣реИ? рд▓реИрдореНрдмреНрдбрд╛ рдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдЦреБрдж рдХреЛ рд╡рд┐рд╕рд░реНрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ cppinsights.io рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рдЙрджрд╛рд╣рд░рдг рдЪрд▓рд╛рдПрдВред рдЕрдЧрд▓рд╛, рдореИрдВрдиреЗ рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рдирд┐рд╖реНрдХрд░реНрд╖ рд╕рдВрд▓рдЧреНрди рдХрд┐рдпрд╛:

class __lambda_60_19
{
public: 
    inline void operator()(int a) const
    {
        std::cout.operator<<(a).operator<<(std::endl);
    }
    
    using retType_60_19 = void (*)(int);
    inline operator retType_60_19 () const noexcept
    {
        return __invoke;
    };
    
private: 
    static inline void __invoke(int a)
    {
        std::cout.operator<<(a).operator<<(std::endl);
    }    
};


рдЗрд╕рд▓рд┐рдП, рдЬрдм рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реИрдореНрдмреНрдбрд╛ рдПрдХ рд╡рд░реНрдЧ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╛ рдПрдХ рдлрд╝рдирдХрд╛рд░ (рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдСрдкрд░реЗрдЯрд░ () рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛрддрд╛ рд╣реИ ) рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдЕрджреНрд╡рд┐рддреАрдп рдирд╛рдо рдХреЗ рд╕рд╛рде, рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдСрдкрд░реЗрдЯрд░ () рд╣реЛрддрд╛ рд╣реИ , рдЬреЛ рдЙрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╣рдордиреЗ рдЕрдкрдиреЗ рдирдВрдмрд╛ рдФрд░ рдЙрд╕рдХреЗ рд╢рд░реАрд░ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдХреЛрдб рдЬрд┐рд╕реЗ рд╣рдорд╛рд░реЗ рд▓рдВрдмреЛрджрд░ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рд╕рд╛рде, рд╕рдм рдХреБрдЫ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреНрдп рджреЛ рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд╣реИ, рд╡реЗ рдХреНрдпреЛрдВ рд╣реИрдВ? рдкрд╣рд▓рд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд▓рд┐рдП рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХрд╛ рдСрдкрд░реЗрдЯрд░ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╣рдорд╛рд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдХреЛрдб рд╣реИ рдЬрд┐рд╕реЗ рддрдм рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рд╣рдорд╛рд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рдЗрд╕рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдкрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

void (*p_lambda) (int) = lambda;
p_lambda(10);

рдареАрдХ рд╣реИ, рд╡рд╣рд╛рдБ рдПрдХ рдкрд╣реЗрд▓реА рд╕реЗ рдХрдо рд╣реИ, рд▓реЗрдХрд┐рди рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рдЖрдЗрдП рд╣рдо рдПрдХ рдХреНрд▓реЛрдЬрд░ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ рдЪрд░ "рдПрдХ" рдХреЛ рд╕рдВрджрд░реНрдн рд╕реЗ рдкрдХрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рд╕реЗ рдмрдврд╝рд╛рддрд╛ рд╣реИред

int main()
{
    int a = 10;
    auto closure = [&a] () { a += 1; };
    closure();
}

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, C ++ рдореЗрдВ рдХреНрд▓реЛрдЬрд░ рдФрд░ рд▓реИрдореНрдмреНрдбрд╛ рдмрдирд╛рдиреЗ рдХрд╛ рддрдВрддреНрд░ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рдЕрдХреНрд╕рд░ рднреНрд░рдорд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд▓реИрдореНрдмреНрдбрд╛ рдФрд░ рдХреНрд▓реЛрдЬрд░ рдХреЛ рдХреЗрд╡рд▓ рд▓реИрдореНрдмреНрдбрд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди C ++ рдореЗрдВ рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдкрд░ рд╡рд╛рдкрд╕ред

class __lambda_61_20
{
public:
    inline void operator()()
    {
        a += 1;
    }
private:
    int & a;
public:
    __lambda_61_20(int & _a)
    : a{_a}
    {}
};

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдордиреЗ рдПрдХ рдирдпрд╛, рдиреЙрди-рдбрд┐рдлреЙрд▓реНрдЯ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдЬреЛрдбрд╝рд╛ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рд╕рдВрджрд░реНрдн рд╕реЗ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдХрдХреНрд╖рд╛ рдХреЗ рд╕рджрд╕реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬрддрд╛ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЖрдкрдХреЛ [рдФрд░] рдпрд╛ [=] рд╕реЗрдЯ рдХрд░рддреЗ рд╕рдордп рдмреЗрд╣рдж рд╕рд╛рд╡рдзрд╛рдиреА рдмрд░рддрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреВрд░реЗ рд╕рдВрджрд░реНрдн рдХреЛ рдмрдВрдж рд╣реЛрдиреЗ рдХреЗ рднреАрддрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдпрд╣ рдореЗрдореЛрд░реА рд╕реЗ рдХрд╛рдлреА рдЙрдк-рд╕реНрддрд░реАрдп рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдордиреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдореЗрдВ рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХреЗ рдСрдкрд░реЗрдЯрд░ рдХреЛ рдЦреЛ рджрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЕрдм рдЗрд╕рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдХреЙрд▓ рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдФрд░ рдЕрдм рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░реЗрдЧрд╛:

int main()
{
    int a = 10;
    auto closure = [&a] () { a += 1; };
    closure();
    void (*ptr)(int) = closure;
}

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдЧрд░ рдЖрдкрдХреЛ рдЕрднреА рднреА рдХрд╣реАрдВ рдкрд╛рд╕ рдмрдВрдж рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдХрд┐рд╕реА рдиреЗ рднреА std :: function рдХрд╛ рдЙрдкрдпреЛрдЧ рд░рджреНрдж рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред

std::function<void()> function = closure;
function();

рдЕрдм рдЬрдм рд╣рдо рд▓рдЧрднрдЧ рд╕рдордЭ рдЧрдП рд╣реИрдВ рдХрд┐ рд▓реИрдореНрдмреНрдбрд╛ рдФрд░ рдХреНрд▓реЛрдЬрд░ C ++ рдореЗрдВ рдХреНрдпрд╛ рд╣реИрдВ, рддреЛ рд╕реАрдзреЗ рдбреЗрдХреЛрд░реЗрдЯрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рд╣рдорд╛рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдкрд░ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдПрдХ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдорд╛рд░реЗ рдлрд╝рдВрдХреНрд╢рди рдпрд╛ рд╡рд┐рдзрд┐ рдХреЛ рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдП, рд╣рдореЗрдВ рдЗрд╕рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛) рдФрд░ рдЬрдм рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдирдпрд╛ рдлрд╝рдВрдХреНрд╢рди рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╣рдорд╛рд░реЗ рдХреЛрдб рдФрд░ рдлрд╝рдВрдХреНрд╢рди / рд╡рд┐рдзрд┐ рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдХреЛрдИ рднреА рд╕реНрд╡рд╛рднрд┐рдорд╛рдиреА рдЕрдЬрдЧрд░ рдХрд╣реЗрдЧрд╛: тАЬрд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХреИрд╕реЗ! рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдореВрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдирд╛рдо рд╕реЗ рдХрд┐рд╕реА рднреА рдХреЙрд▓ рдХреЛ рдПрдХ рдирдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП! " рдмрд╕ рдпрд╣ C ++ рдХреА рдореБрдЦреНрдп рд╕реАрдорд╛ рд╣реИ, рд╣рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдкреБрд░рд╛рдиреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВред рдмреЗрд╢рдХ, рдЗрд╕рдХреЗ рдкрддреЗ рдХреЛ рд╕реНрдореГрддрд┐ рдореЗрдВ рд▓рд╛рдиреЗ рдФрд░ рдЗрд╕реЗ рдкреАрд╕рдиреЗ рдХрд╛ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреА рдЕрд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдкреНрддрд┐ рд╣реЛ рдЬрд╛рдПрдЧреА) рдпрд╛ рдЗрд╕рдХреЗ рд╢рд░реАрд░ рдХреЛ рдПрдХ рдЪреЗрддрд╛рд╡рдиреА рдХреЗ рд╕рд╛рде рдмрджрд▓реЗрдВ рдХрд┐ рдЗрд╕реЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдпрд╣ рдЧрдВрднреАрд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рднрд░рд╛ рд╣реИред рдпрджрд┐ рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдмрд┐рд▓реНрдХреБрд▓ рдХрдард┐рди рд▓рдЧрддрд╛ рд╣реИ,рддрдм рджреВрд╕рд░рд╛ рд╕рдВрдХрд▓рдХ, рдЬрдм рд╡рд┐рднрд┐рдиреНрди рд╕рдВрдХрд▓рдХ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рджреБрд░реНрдШрдЯрдирд╛ рднреА рд╣реЛ рд╕рдХрддреА рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрд┐рд╕реА рднреА рдореИрдХреНрд░реЛ рдореИрдЬрд┐рдХ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдореИрдВ рдмреЗрдорд╛рдиреА рдорд╛рдирддрд╛ рд╣реВрдВред

рддреЛ, рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝реЗрдВред рдореЗрд░реЗ рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрдпрд╛ рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдпрд╣ рдерд╛:

namespace Decorator
{
    template<typename R, typename ...Args>
    static auto make(const std::function<R(Args...)>& f)
    {
        std::cout << "Do something" << std::endl;
        return [=](Args... args) 
        {
            return f(std::forward<Args>(args)...);
        };
    }
};

рдЗрд╕реЗ рдПрдХ рд╕реНрдЯреИрдЯрд┐рдХ рдореЗрдердб рд╡рд╛рд▓рд╛ рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдмрдирд╛рдЗрдП рдЬреЛ std :: function рдХреЛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдПрдХ рдХреНрд▓реЛрдЬрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рдлрдВрдХреНрд╢рди рдХреЗ рд╕рдорд╛рди рдкреИрд░рд╛рдореАрдЯрд░ рд▓реЗрдЧрд╛ рдФрд░ рдЬрдм рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рддреЛ рдпрд╣ рд╕рд┐рд░реНрдл рд╣рдорд╛рд░реЗ рдлрдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛ рдФрд░ рдЗрд╕рдХрд╛ рд░рд┐рдЬрд▓реНрдЯ рд▓реМрдЯрд╛рдПрдЧрд╛ред

рдЪрд▓реЛ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдПрдВ рдЬрд┐рд╕реЗ рд╣рдо рд╕рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд╛рд╣рддреЗ рд╣реИрдВред

void myFunc(int a)
{
    std::cout << "here" << std::endl;
}

рдФрд░ рд╣рдорд╛рд░рд╛ рдореБрдЦреНрдп рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

int main()
{
    std::function<void(int)> f = myFunc;
    auto decorated = Decorator::make(f);
    decorated(10);
}


рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╕рдм рдХреБрдЫ рдареАрдХ рд╣реИ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╣реБрд░реНрд░реЗ рд╣реИред

рджрд░рдЕрд╕рд▓, рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рдЪрд▓реЛ рдХреНрд░рдо рдореЗрдВ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

  1. рдпрд╣ рдХреЛрдб рдХреЗрд╡рд▓ рд╕рдВрд╕реНрдХрд░рдг C ++ 14 рдФрд░ рдЙрдЪреНрдЪрддрд░ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рд▓реМрдЯрд╛рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХреЛ рдЬрд╛рдирдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рд░рд╣рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдореБрдЭреЗ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рдорд┐рд▓реЗред
  2. рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП std :: рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЗрд╕рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд╛рдо рд╕реЗ рдкрд╛рд╕ рдХрд░рдиреЗ рд╕реЗ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реЛрддреА рд╣реИрдВред рдФрд░ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИ рдЬрд┐рддрдирд╛ рд╣рдо рдЪрд╛рд╣реЗрдВрдЧреЗ! рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЛрдб рдирд╣реАрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

    Decorator::make([](){});
    Decorator::make(myFunc);
    void(*ptr)(int) = myFunc;
    Decorator::make(ptr);

  3. рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рд╡рд░реНрдЧ рд╡рд┐рдзрд┐ рдХреЛ рд╕рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред

рдЗрд╕рд▓рд┐рдП, рд╕рд╣рдХрд░реНрдорд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЫреЛрдЯреА рдмрд╛рддрдЪреАрдд рдХреЗ рдмрд╛рдж, C ++ 17 рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рдж рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛:

namespace Decorator
{
    template<typename Function>
    static auto make(Function&& func)
    {
        return [func = std::forward<Function>(func)] (auto && ...args) 
        {
            std::cout << "Do something" << std::endl;
            return std::invoke(
                func,
                std::forward<decltype(args)>(args)...
            );
        };
    }
};

рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдлрд╛рдпрджреЗ рдпрд╣ рд╣реИрдВ рдХрд┐ рдЕрдм рд╣рдо рдХрд┐рд╕реА рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рдСрдкрд░реЗрдЯрд░ () рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ ред рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдирд┐: рд╢реБрд▓реНрдХ рдлрд╝рдВрдХреНрд╢рди, рдПрдХ рдкреЙрдЗрдВрдЯрд░, рдПрдХ рд▓реИрдореНрдмреНрдбрд╛, рдХрд┐рд╕реА рднреА рдлрд╝рдирдХрд╛рд░, рдПрд╕рдЯреАрдбреА :: рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдХреНрд▓рд╛рд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдмрд╛рдж рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдбрд┐рдХреЛрдб рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрджрд░реНрдн рдкрд╛рд╕ рдХрд░рдирд╛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рдЖрд╡реЗрджрди рдХреЗ рд╡рд┐рдХрд▓реНрдк
int main()
{
    auto decorated_1 = Decorator::make(myFunc);
    decorated_1(1,2);

    auto my_lambda = [] (int a, int b) 
    { 
        std::cout << a << " " << b <<std::endl; 
    };
    auto decorated_2 = Decorator::make(my_lambda);
    decorated_2(3,4);

    int (*ptr)(int, int) = myFunc;
    auto decorated_3 = Decorator::make(ptr);
    decorated_3(5,6);

    std::function<void(int, int)> fun = myFunc;
    auto decorated_4 = Decorator::make(fun);
    decorated_4(7,8);

    auto decorated_5 = Decorator::make(decorated_4);
    decorated_5(9, 10);

    auto decorated_6 = Decorator::make(&MyClass::func);
    decorated_6(MyClass(10));
}


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рдХреЛрдб рдХреЛ C ++ 14 рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ std :: invoke рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИ, рдЬрд┐рд╕реЗ std :: __ invoke рд╕реЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдХреЛрдИ рд╡рд┐рд╕реНрддрд╛рд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдХрдХреНрд╖рд╛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд╕рдЬрд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдЫреЛрдбрд╝рдиреА рд╣реЛрдЧреА, рдФрд░ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЕрдиреБрдкрд▓рдмреНрдз рд╣реЛ рдЬрд╛рдПрдЧреАред

рдмреЛрдЭрд┐рд▓ рдирд╣реАрдВ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП "std :: forward <рдШреЛрд╖рдгрд╛рдкрддреНрд░ (args)> (args) ..." рдЖрдк C ++ 20 рдХреЗ рд╕рд╛рде рдЙрдкрд▓рдмреНрдз рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╣рдорд╛рд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ!

namespace Decorator
{
    template<typename Function>
    static auto make(Function&& func)
    {
        return [func = std::forward<Function>(func)] 
        <typename ...Args> (Args && ...args) 
        {
            return std::invoke(
                func,
                std::forward<Args>(args)...
            );
        };
    }
};

рд╕рдм рдХреБрдЫ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИ рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рдпрд╛ рдХрдо рд╕реЗ рдХрдо рджрд┐рдЦрд╛рд╡рд╛) рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХреЛрдб gcc рдФрд░ clang 10-x рджреЛрдиреЛрдВ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рд┐рдд рд╣реИ рдФрд░ рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдБ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ ред рд╡рд┐рднрд┐рдиреНрди рдорд╛рдирдХреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднреА рд╣реЛрдВрдЧреЗред

рдЕрдЧрд▓реЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ, рд╣рдо рдкрд╛рдпрдерди рдЙрджрд╛рд╣рд░рдг рдФрд░ рдЙрдирдХреА рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдЬреНрдЬрд╛рдХрд╛рд░реЛрдВ рдХреЗ рд╡рд┐рд╣рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗред

All Articles