C ++ рд╡реИрд░реЗрдбрд┐рдХ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛

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

рддреЛ рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд╕реНрддреБ рд╣реИ:

class Elephant { public: std::string touch_leg() { return "it's like a pillar"; } std::string touch_trunk() { return "it's like a snake"; } std::string touch_tail() { return "it's like a rope"; } void run_away() { m_is_gone = true; std::cout << "*** Sound of running out elephant ***\n"; } bool is_elephant_here() { return !m_is_gone; } private: bool m_is_gone = false; }; 

рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 3 рд╣реИрдВрдбрд▓рд░ рд╣реЛрдВрдЧреЗ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдЖрдЧреЗ рдХреА рд╡рд╕реНрддреБ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдЧрд╛:

 //        auto blind_sage3 = ChainOfRepsonsibility::start_new([](Elephant& e) { std::cout << "Third blind sage: " << e.touch_tail() << "\n"; }); // ""    ,     auto blind_sage2 = blind_sage3.attach([](Elephant& e, auto& next) { std::cout << "Second blind sage: " << e.touch_trunk() << "\n"; next(e); }); //    ,     ,    auto blind_sage1 = blind_sage2.attach([](Elephant& e, auto& next) { if (!e.is_elephant_here()) { std::cout << "First blind sage: So empty... so true\n"; } else { std::cout << "First blind sage: " << e.touch_leg() << "\n"; next(e); } }); //      Elephant e; blind_sage1(e); 

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

рдпрд╣рд╛рдБ рд╡рд░реНрдЧ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реНрд╡рдпрдВ рд╣реИ:

 #include <functional> struct ChainOfRepsonsibility { template<typename... Args> struct Chain { template<typename Callee, typename Next> Chain(const Callee c, const Next& n) { m_impl = c; m_next = n; } template<typename Callee> decltype(auto) attach(Callee c) { return Chain(c, *this); } void operator()(Args... e) { m_impl(e..., m_next); } std::function<void(Args..., std::function<void(Args...)>)> m_impl; std::function<void(Args...)> m_next; }; template<typename... Args> struct ChainTail { template<typename Callee> ChainTail(Callee c) { m_impl = c; } template<typename Callee> decltype(auto) attach(Callee c) { return Chain<Args...>(c, m_impl); } void operator()(Args... e) { m_impl(e...); } std::function<void(Args... e)> m_impl; }; template<typename> struct StartChain; template<typename C, typename... Args> struct StartChain<void (C::*)(Args...) const> { using Type = ChainTail<Args...>; }; template<typename Callee> static decltype(auto) start_new(Callee c) { return StartChain<decltype(&Callee::operator())>::Type(c); } }; 

рдпрд╣ рдЗрд╕ рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:

  • рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо start_new рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдмрдирд╛рддреЗ рд╣реИрдВред рдЗрд╕ рд╕реНрддрд░ рдкрд░ рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдкрд╛рд╕ рд╣реБрдП рд▓рдВрдмреЛ рд╕реЗ рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рдЙрдирдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣реИрдВрдбрд▓рд░ рдХрд╛ "рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк" рдмрдирд╛рдПрдВред
  • рд▓реИрдореНрдмреНрдбрд╛ рдХреЗ рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрдЯрд╛рд░реНрдЯрдЪреИрди рдХреНрд▓рд╛рд╕ рдФрд░ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдореБрд╢реНрдХрд┐рд▓ рд╡рд┐рд╖рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдХрдХреНрд╖рд╛ рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕рдВрд╕реНрдХрд░рдг рдШреЛрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╕реНрдкреЗрд╢рд▓рд╛рдЗрдЬреЗрд╢рди рд╕реНрдЯреНрд░рдХреНрдЪрд░ StartChain <void (C :: *) (Args ...) const> ред рдпрд╣ рдирд┐рд░реНрдорд╛рдг рд╣рдореЗрдВ рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдХрдХреНрд╖рд╛ рд╕рджрд╕реНрдп рджреНрд╡рд╛рд░рд╛ рддрд░реНрдХ рд╕реВрдЪреА рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
  • рддрд░реНрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪреЗрдирдЯреЗрд▓ рдФрд░ рдЪреЗрди рдХреНрд▓рд╛рд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╣реИрдВрдбрд▓рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрд╡рд░рдг рд╣реЛрдЧрд╛ред рдЙрдирдХрд╛ рдХрд╛рд░реНрдп ldda рдХреЛ std :: рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рд╣реЗрдЬрдирд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рд╣реА рд╕рдордп рдкрд░ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реИ, рд╕рд╛рде рд╣реА рд╕рдВрд▓рдЧреНрди рдкрджреНрдзрддрд┐ (рдКрдкрд░ рд╕реЗ рд╣реИрдВрдбрд▓рд░ рд╕реЗрдЯ рдХрд░рдирд╛) рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реИред

рджреГрд╢реНрдп рд╕реНрдЯреВрдбрд┐рдпреЛ 2015 рдкрд░ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, gcc рдХреЗ рд▓рд┐рдП рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╡рд╣рд╛рдВ рд╕реЗ рдХрд╛рд╕реНрдЯ рд╣рдЯрд╛рдХрд░ StartChain рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рдареАрдХ рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЕрдЧрд░ lambdas рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдЖрдк рдмрд╕ рдлрд╝рдВрдХреНрд╢рди рдкрд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдПрдХ рдФрд░ StartChain рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдЕрднреА рднреА рдЕрдиреБрд▓рдЧреНрдирдХ рдореЗрдВ рдирдХрд▓ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХрджрдо рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЬрдЯрд┐рд▓ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдорд╛рдорд▓реЗ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ред

Source: https://habr.com/ru/post/hi413765/


All Articles