ADL рд╕рдВрдкрд░реНрдХ рдмрдВрдж рдХрд░реЗрдВ


рдЗрддрд┐рд╣рд╛рд╕ рдореЗрдВ рдЕрдкрдирд╛ рдирд╛рдо рд╣рдореЗрд╢рд╛ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВ? рдЪрд╛рдВрдж рдкрд░ рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рдЙрдбрд╝рд╛рди? рдПрдХ рд╡рд┐рджреЗрд╢реА рджрд┐рдорд╛рдЧ рд╕реЗ рдорд┐рд▓рдиреЗ рд╡рд╛рд▓рд╛ рдкрд╣рд▓рд╛? рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд░рд▓ рддрд░реАрдХрд╛ рд╣реИ - рдЖрдк рдЦреБрдж рдХреЛ C ++ рднрд╛рд╖рд╛ рдорд╛рдирдХ рдореЗрдВ рдлрд┐рдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рд╕реА ++ рд░реЗрдВрдЬ рдХреЗ рд▓реЗрдЦрдХ рдПрд░рд┐рдХ рдирд┐рдмрд▓рд░ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред тАЬрдпрд╣ рдпрд╛рдж рд░рдЦреЛред 19 рдлрд░рд╡рд░реА, 2019 рд╡рд╣ рджрд┐рди рд╣реИ, рдЬрдм рд╢рдмреНрдж "nibloid" рдкрд╣рд▓реА рдмрд╛рд░ WG21 рдХреА рдмреИрдардХ рдореЗрдВ рдмреЛрд▓рд╛ рдЧрдпрд╛ рдерд╛, рдЙрдиреНрд╣реЛрдВрдиреЗ рдЯреНрд╡рд┐рдЯрд░ рдкрд░ рд▓рд┐рдЦрд╛ рдерд╛ред


рджрд░рдЕрд╕рд▓, рдЕрдЧрд░ рдЖрдк CppReference рдореЗрдВ , cpp / algorithm / rangescpp / рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо / рдкрд░реНрд╡рддрдорд╛рд▓рд╛ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ , рддреЛ рдЖрдкрдХреЛ рд╡рд╣рд╛рдВ рдХрдИ рд╕рдВрджрд░реНрдн рдорд┐рд▓реЗрдВрдЧреЗ (niebloid)ред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдПрдХ рдЕрд▓рдЧ dsc_niebloid рд╡рд┐рдХреА рдЯреЗрдореНрдкреНрд▓реЗрдЯ рднреА рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред


рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдХреЛрдИ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкреВрд░реНрдг рд▓реЗрдЦ рдирд╣реАрдВ рдорд┐рд▓рд╛ рдФрд░ рдореИрдВрдиреЗ рдЦреБрдж рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдпрд╣ рд╡рд╛рд╕реНрддреБ рдЕрдВрддрд░рд┐рдХреНрд╖ рдпрд╛рддреНрд░рд┐рдпреЛрдВ рдХреЗ рд░рд╕рд╛рддрд▓ рдореЗрдВ рдПрдХ рдЫреЛрдЯреА рд▓реЗрдХрд┐рди рдЖрдХрд░реНрд╖рдХ рдпрд╛рддреНрд░рд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╣рдо ADL рдкрд╛рдЧрд▓рдкрди рдХреЗ рд░рд╕рд╛рддрд▓ рдореЗрдВ рдбреБрдмрдХреА рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ nibloids рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


рдорд╣рддреНрд╡рдкреВрд░реНрдг: рдореИрдВ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реЗрд▓реНрдбрд░ рдирд╣реАрдВ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдПрдХ рдЬрд╛рд╡реЗрдж рдЬреЛ рдХрднреА-рдХрднреА рдЖрд╡рд╢реНрдпрдХ рд╕реА ++ рдХреЛрдб рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдареАрдХ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рддрд░реНрдХ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рд╕рдордп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред "рджрд╢рд╛ рдореЗрдВ рдорджрдж рдХрд░реЗрдВ рдпрд╛рддреНрд░реА рдХреБрдЫ рдЙрдЪрд┐рдд рдЗрдХрдЯреНрдард╛ рдХрд░реЗрдВред"


рд▓реБрдХ


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


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, C ++ рдореЗрдВ рдПрдХ рдирд╛рдо рдЦреЛрдЬ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИ рдпрд╛, рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдПрдХ рд▓реБрдХрдЕрдк: рдЬрдм рдХрд┐рд╕реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рдХреЛрдИ рдирд╛рдо рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рд╡рд╣ рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдЗрд╕рдХреА рдШреЛрд╖рдгрд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред


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


ADL


рдпрджрд┐ рд▓реБрдХрдЕрдк рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдирд╛рдо рдХрд╣рд╛рдБ рджреЗрдЦрдирд╛ рд╣реИред рдФрд░ рдпрд╣рд╛рдВ ADL рдирд╛рдордХ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕реБрд╡рд┐рдзрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ: рддрд░реНрдХ-рдирд┐рд░реНрднрд░ рд▓реБрдХрдЕрдк , рдпрд╛ рдлрд┐рд░ - рдХреЛрдПрдирд┐рдЧ рдХреА рдЦреЛрдЬ (рдЬрд┐рд╕рдиреЗ "рд╡рд┐рд░реЛрдзреА рдкреИрдЯрд░реНрди" рд╢рдмреНрдж рдЧрдврд╝рд╛, рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд╛рда рдХреЗ рдкреНрд░рдХрд╛рд╢ рдореЗрдВ рдереЛрдбрд╝рд╛ рдкреНрд░рддреАрдХрд╛рддреНрдордХ рд╣реИ)ред рдирд┐рдХреЛрд▓рдИ рдЬреЛрд╕реБрдЯрд┐рд╕ рдиреЗ рдЕрдкрдиреА рдкреБрд╕реНрддрдХ "рдж рд╕реА ++ рд╕реНрдЯреИрдВрдбрд░реНрдб рд▓рд╛рдЗрдмреНрд░реЗрд░реА: рдП рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдПрдВрдб рд░реЗрдлрд░реЗрдВрд╕" рдореЗрдВ рдЗрд╕рдХрд╛ рд╡рд░реНрдгрди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ: "рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдирд╛рдорд╕реНрдерд╛рди рдХреЛ рдЕрд░реНрд╣рддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдХрдо рд╕реЗ рдХрдо рдПрдХ рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдирд╛рдо рд╕реНрдерд╛рди рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред"


рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП?


 #include <iostream> int main() { //  . //   , operator<<    ,  ADL , //    std    std::operator<<(std::ostream&, const char*) std::cout << "Test\n"; //    .      -     . operator<<(std::cout, "Test\n"); // same, using function call notation //    : // Error: 'endl' is not declared in this namespace. //      endl(),  ADL  . std::cout << endl; //  . //    ,       ADL. //     std,   endl      std. endl(std::cout); //    : // Error: 'endl' is not declared in this namespace. //  ,  - (endl) -     . (endl)(std::cout); } 

ADL рдХреЗ рд╕рд╛рде рдирд░рдХ рдореЗрдВ рдЙрддрд░реЛ


рдпрд╣ рд╕рд░рд▓ рдкреНрд░рддреАрдд рд╣реЛрдЧрд╛ред рдпрд╛ рдирд╣реАрдВ? рдкрд╣рд▓реЗ, рддрд░реНрдХ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрдбреАрдПрд▓ рдиреМ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ , рдЭрд╛рдбрд╝реВ рдХреЗ рд╕рд╛рде рдорд╛рд░рдиреЗ рдХреЗ рд▓рд┐рдПред


рджреВрд╕рд░реЗ, рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ, рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕реНрд╡реИрдк рдХрд╛рд░реНрдп рд╣реИред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ std::swap(obj1,obj2); рдФрд░ using std::swap; swap(obj1, obj2); using std::swap; swap(obj1, obj2); рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ ADL рд╕рдХреНрд╖рдо рд╣реИ, рддреЛ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрд╡реИрдк рд╕реЗ, рдЖрдкрдХреЛ рдЬрд┐рд╕ рдЪреАрдЬрд╝ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╡рд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рддрд░реНрдХреЛрдВ рдХреЗ рдирд╛рдо рд╕реНрдерд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЪреБрдиреА рдЧрдИ рд╣реИ! рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЗрд╕ рдореБрд╣рд╛рд╡рд░реЗ рдХреЛ рд╕рдХрд╛рд░рд╛рддреНрдордХ рдФрд░ рдирдХрд╛рд░рд╛рддреНрдордХ рдЙрджрд╛рд╣рд░рдг рджреЛрдиреЛрдВ рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ :-)


рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рд╣реИрдЯ рдХреЗ рдУрд╡рди рдореЗрдВ рдЬрд▓рд╛рдК рд▓рдХрдбрд╝реА рдХреЛ рдЧрд┐рд░рд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЖрд░реНрдерд░ рдУ'рдбрд╛рдпрд░ рджреНрд╡рд╛рд░рд╛ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛ред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдЕрдкрдиреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рджрдВрдб рдирд╣реАрдВ рджреЗрдВрдЧреЗред


рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реИ:


 #include <stdio.h> namespace A { struct A {}; void call(void (*f)()) { f(); } } void f() { puts("Hello world"); } int main() { call(f); } 

рдмреЗрд╢рдХ, рдпрд╣ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рд╣реИ:


 error: use of undeclared identifier 'call'; did you mean 'A::call'? call(f); ^~~~ A::call 

рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдлрд╝рдВрдХреНрд╢рди f рдХрд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрдкреНрд░рдпреБрдХреНрдд рдЕрдзрд┐рднрд╛рд░ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░реЗрдЧрд╛!


 #include <stdio.h> namespace A { struct A {}; void call(void (*f)()) { f(); } } void f() { puts("Hello world"); } void f(A::A); // UNUSED int main() { call(f); } 

рд╡рд┐рдЬреБрдЕрд▓ рд╕реНрдЯреВрдбрд┐рдпреЛ рдкрд░ рдпрд╣ рдЕрднреА рднреА рдЯреВрдЯ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдЙрд╕рдХрд╛ рднрд╛рдЧреНрдп рд╣реИ, рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред


рдпрд╣ рдХреИрд╕реЗ рд╣реБрдЖ? рдЖрдЗрдП рдорд╛рдирдХ рдореЗрдВ рддрдмреНрджреАрд▓ рдХрд░реЗрдВ (рдЕрдиреБрд╡рд╛рдж рдХреЗ рдмрд┐рдирд╛, рдХреНрдпреЛрдВрдХрд┐ рдРрд╕рд╛ рдЕрдиреБрд╡рд╛рдж buzzwords рдХрд╛ рдЕрд╕рд╛рдзрд╛рд░рдг рд░реВрдк рд╕реЗ рд░рд╛рдХреНрд╖рд╕реА рдорд┐рд╖рдо рд╣реЛрдЧрд╛):


рдпрджрд┐ рддрд░реНрдХ рдЕрддрд┐рднрд╛рд░рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдФрд░ / рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗ рд╕реЗрдЯ рдХрд╛ рдирд╛рдо рдпрд╛ рдкрддрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреА рд╕рдВрдмрджреНрдз рдЗрдХрд╛рдЗрдпрд╛рдБ рдФрд░ рдирд╛рдорд╕реНрдерд╛рди рд╕реЗрдЯ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕рджрд╕реНрдп рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд╕рдВрдШ рд╣реИрдВ, рдЕрд░реНрдерд╛рддреН, рдЗрд╕рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗ рдЬреБрдбрд╝реА рд╕рдВрд╕реНрдерд╛рдПрдБ рдФрд░ рдирд╛рдорд╕реНрдерд╛рдиред рдкреНрд░рдХрд╛рд░ рдФрд░ рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ред [...] рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдпрджрд┐ рдУрд╡рд░рд▓реЛрдб рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдкреВрд░реНрд╡реЛрдХреНрдд рд╕реЗрдЯ рдХреЛ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ-рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рдирд╛рдорд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЗрд╕рдХреЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд┐рдХрд╛рдп рдФрд░ рдирд╛рдорд╕реНрдерд╛рди рдореЗрдВ рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ-рддрд░реНрдХ рдФрд░ рдЗрд╕рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ-рддрд░реНрдХ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

рдЕрдм рдПрдХ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рд▓реЗрдВ:


 #include <stdio.h> namespace B { struct B {}; void call(void (*f)()) { f(); } } template<class T> void f() { puts("Hello world"); } int main() { call(f<B::B>); } 

рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдРрд╕реЗ рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдЬрд┐рдирдХрд╛ рдХреЛрдИ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИред f рдФрд░ f<B::B> рдУрд╡рд░рд▓реЛрдбреЗрдб рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рд╕реЗрдЯ рдХреЗ рдирд╛рдо рд╣реИрдВ (рдКрдкрд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рд╕реЗ), рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕реЗрдЯ рдХрд╛ рдХреЛрдИ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИред рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдЕрдзрд┐рднрд╛рд░ рдХреЛ рдврд╣рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ call рдЕрдзрд┐рднрд╛рд░ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рд╣реИред рддреЛ, рдЖрдкрдХреЛ call рд▓рд┐рдП рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рд▓реБрдХрдЕрдк call рдЪрд▓рд╛рдирд╛ред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП ADL рд╢реБрд░реВ рд╣реЛрдЧрд╛!


рд▓реЗрдХрд┐рди рдЖрдорддреМрд░ рдкрд░ ADL рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рддрд░реНрдХреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рд┐рдП! рдФрд░ рдпрд╣рд╛рдВ рдХреНрд▓реИрдВрдЧ, рдЖрдИрд╕реАрд╕реА рдФрд░ MSVC рдЧрд▓рддреА рд╕реЗ рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИ (рд▓реЗрдХрд┐рди рдЬреАрд╕реАрд╕реА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ):


 [build] ..\..\main.cpp(15,5): error: use of undeclared identifier 'call'; did you mean 'B::call'? [build] call(f<B::B>); [build] ^~~~ [build] B::call [build] ..\..\main.cpp(4,10): note: 'B::call' declared here [build] void call(void (*f)()) { [build] ^ 

рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдбреАрдПрд▓ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рдХ рдХреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдХрд╛ рдереЛрдбрд╝рд╛ рддрдирд╛рд╡рдкреВрд░реНрдг рд╕рдВрдмрдВрдз рд╣реИред


рдЕрдЪреНрдЫрд╛, рдХреНрдпрд╛ ADL рдЕрднреА рднреА рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ? рдПрдХ рдУрд░, рд╣рдореЗрдВ рд╡рд┐рдирдореНрд░ рддрд░реАрдХреЗ рд╕реЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕реНрд▓рд╛рд╡ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ:


 std::cout << "Hello, World!" << std::endl; std::operator<<(std::operator<<(std::cout, "Hello, World!"), "\n"); 

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


рд░рдВрдЧ рдФрд░ рдЕрд╡рдзрд╛рд░рдгрд╛рдПрдБ


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


рдХреЙрдиреНрд╕реЗрдкреНрдЯ рдХреЛ рдмрд╛рдзрд╛рдУрдВ рдХрд╛ рдирд╛рдо рд╕реЗрдЯ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреЗ рдлрд╝рдВрдХреНрд╢рди рдУрд╡рд░рд▓реЛрдб рдФрд░ рд╕рдмрд╕реЗ рдЙрдкрдпреБрдХреНрдд рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛рдУрдВ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯреЗрдореНрдкрд▓реЗрдЯ рддрд░реНрдХреЛрдВ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВред


 template <typename T> concept bool HasStringFunc = requires(T a) { { to_string(a) } -> string; }; void print(HasStringFunc a) { cout << to_string(a) << endl; } 

рдпрд╣рд╛рдВ рд╣рдордиреЗ рдПрдХ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рдпрд╛ рд╣реИ рдХрд┐ рддрд░реНрдХ рдореЗрдВ рдПрдХ to_string рдлрд╝рдВрдХреНрд╢рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╣рдо print рднреАрддрд░ рдХреБрдЫ рдЧреЗрдо рдбрд╛рд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЗ рддрд╣рдд рдирд╣реАрдВ рдЖрддреЗ рд╣реИрдВ, рддреЛ рдРрд╕реЗ рдХреЛрдб рдмрд╕ рд╕рдВрдХрд▓рди рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред


рдпрд╣ рдХреЛрдб рдХреЛ рдмрд╣реБрдд рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рджреЗрдЦреЗрдВ рдХрд┐ рдирд┐рдмрд▓рд░ рдиреЗ рд░реЗрдВрдЬ-рд╡реА 3 рдореЗрдВ рдЫрдВрдЯрд╛рдИ рдХреИрд╕реЗ рдХреА, рдЬреЛ рд╕реА ++ 11/14/17 рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдПрдХ рдЕрджреНрднреБрдд рдХреЛрдб рд╣реИ:


 #define CONCEPT_PP_CAT_(X, Y) X ## Y #define CONCEPT_PP_CAT(X, Y) CONCEPT_PP_CAT_(X, Y) /// \addtogroup group-concepts /// @{ #define CONCEPT_REQUIRES_(...) \ int CONCEPT_PP_CAT(_concept_requires_, __LINE__) = 42, \ typename std::enable_if< \ (CONCEPT_PP_CAT(_concept_requires_, __LINE__) == 43) || (__VA_ARGS__), \ int \ >::type = 0 \ /**/ 

рддрд╛рдХрд┐ рдмрд╛рдж рдореЗрдВ рдЖрдк рдРрд╕рд╛ рдХрд░ рд╕рдХреЗрдВ:


 struct Sortable_ { template<typename Rng, typename C = ordered_less, typename P = ident, typename I = iterator_t<Rng>> auto requires_() -> decltype( concepts::valid_expr( concepts::model_of<concepts::ForwardRange, Rng>(), concepts::is_true(ranges::Sortable<I, C, P>()) )); }; using Sortable = concepts::models<Sortable_, Rng, C, P>; template<typename Rng, typename C = ordered_less, typename P = ident, CONCEPT_REQUIRES_(!Sortable<Rng, C, P>())> void operator()(Rng &&, C && = C{}, P && = P{}) const { ... 

рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдпрд╣ рд╕рдм рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ рдФрд░ рдмрд╕ рдПрдХ рддрд╛рдЬрд╛ рд╕рдВрдХрд▓рдХ рдореЗрдВ рддреИрдпрд╛рд░ рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред


рдЕрдиреБрдХреВрд▓рди рдЕрдВрдХ


рдЕрдЧрд▓реА рджрд┐рд▓рдЪрд╕реНрдк рдЪреАрдЬ рдЬреЛ рдорд╛рдирдХ рдореЗрдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ рд╡рд╣ рд╣реИ custom.point.object ред рд╡реЗ рдирд┐рдмрд▓рд░ рд░реЗрдВрдЬреНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред


рдЕрдиреБрдХреВрд▓рди рдмрд┐рдВрджреБ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рддрд╛рдХрд┐ рдЗрд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдирд╛рдорд╕реНрдерд╛рди рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рднрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗ, рдФрд░ рдпреЗ рдЕрдзрд┐рднрд╛рд░ ADL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдЕрдиреБрдХреВрд▓рди рдЕрдВрдХ cust рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд╛рд╕реНрддреБ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рд╕рд╛рде рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдП рдЧрдП cust ( cust рдХреБрдЫ рдХрд╛рд▓реНрдкрдирд┐рдХ рдЕрдиреБрдХреВрд▓рди рдмрд┐рдВрджреБ рдХрд╛ рдирд╛рдо рд╣реИ):


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

рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рд╣реИ, рдЖрдк N4381 рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ ред рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рд╡реЗ begin , swap , data рдФрд░ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдЕрдкрдиреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрд░рд╣ рд╕реЗ рджрд┐рдЦрддреЗ рд╣реИрдВ, рдФрд░ рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдПрдбреАрдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдиреНрд╣реЗрдВ рдЪреБрдирддрд╛ рд╣реИред


рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдкреБрд░рд╛рдиреА рдкреНрд░рдерд╛ рд╕реЗ рдЕрд▓рдЧ рдХреИрд╕реЗ рд╣реИ, рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдирд╛рдо рд╕реНрдерд╛рди рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдзрд┐рднрд╛рд░ рд▓рд┐рдЦрддрд╛ рд╣реИ? рдФрд░ рд╡реЗ рд╡рд╕реНрддреБрдПрдВ рднреА рдХреНрдпреЛрдВ рд╣реИрдВ?


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


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


рдЕрдиреБрдХреВрд▓рди рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд▓рд┐рдП рд╡рд░реНрддрдорд╛рди рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдХреБрдЫ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рдм рдХреБрдЫ рддреЛрдбрд╝рдирд╛ рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИред рдЗрд╕ рдХреЛрдб рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ:


 template<class T> void f(T& t1, T& t2) { using std::swap; swap(t1, t2); } 

рдЕрдЧрд░ рд╣рдо рдЧрд▓рддреА рд╕реЗ std::swap(t1, t2) рд▓рд┐рдП рдПрдХ рдпреЛрдЧреНрдп рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ std::swap(t1, t2) рддреЛ рд╣рдорд╛рд░реЗ swap рдХрд╛ рдЕрдкрдирд╛ рд╕рдВрд╕реНрдХрд░рдг рдХрднреА рднреА рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЪрд╛рд╣реЗ рд╣рдо рд╡рд╣рд╛рдВ рдХреЛрдИ рднреА рдЪреАрдЬ рдбрд╛рд▓ рджреЗрдВред рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрд╕реНрдЯрдо рдлрдВрдХреНрд╢рди рдЗрдореНрдкреНрд▓реАрдореЗрдВрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП рд╕реЗрдВрдЯреНрд░рд▓реА рд╕реЗрдВрд╕реЗрд╢рди рдЪреЗрдХ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред N4381 рдореЗрдВ рд╡реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ:


"рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рдХрд┐рд╕реА рджрд┐рди, std::begin рдХреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдХрд┐ рдЗрд╕рдХреЗ рддрд░реНрдХ рдХреЛ рдПрдХ Range рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЗрд╕ рддрд░рд╣ рдХреЗ рдкреНрд░рддрд┐рдмрдВрдз рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╕реЗ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореБрд╣рд╛рд╡рд░реЗ рдкрд░ рдХреЛрдб рдкрд░ рдХреЛрдИ рдкреНрд░рднрд╛рд╡ рдирд╣реАрдВ рдкрдбрд╝реЗрдЧрд╛ std::begin start:


 using std::begin; begin(a); 

рдЖрдЦрд┐рд░рдХрд╛рд░, рдпрджрд┐ begin рдХреЙрд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдмрдирд╛рдП рдЧрдП рдУрд╡рд░рд▓реЛрдб рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рднреЗрдЬ рджреА рдЬрд╛рддреА рд╣реИ, рддреЛ std::begin рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рдХреЗрд╡рд▓ рдЕрдирджреЗрдЦрд╛ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред тАЭ


рдкреНрд░реЛрдкреЛрдЬрд╝рд▓ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╕рдорд╛рдзрд╛рди рджреЛрдиреЛрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо std::begin рдЗрд╕ рд╕рдЯреНрдЯрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ std::begin start (рдЖрдк Godbolt рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ):


 #include <utility> namespace my_std { namespace detail { struct begin_fn { /*   ,         begin(arg)  arg.begin().  -   . */ template <class T> auto operator()(T&& arg) const { return impl(arg, 1L); } template <class T> auto impl(T&& arg, int) const requires requires { begin(std::declval<T>()); } { return begin(arg); } // ADL template <class T> auto impl(T&& arg, long) const requires requires { std::declval<T>().begin(); } { return arg.begin(); } // ... }; } //        inline constexpr detail::begin_fn begin{}; } 

рдХреБрдЫ my_std::begin(someObject) рдПрдХ рдпреЛрдЧреНрдп рдХреЙрд▓ рд╣рдореЗрд╢рд╛ my_std::detail::begin_fn - рдФрд░ рдЗрд╕рд╕реЗ рдЕрдЪреНрдЫреА рд╣реЛрддреА рд╣реИред рдПрдХ рдЕрдпреЛрдЧреНрдп рдХреЙрд▓ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ? рдЖрдЗрдП рдлрд┐рд░ рд╕реЗ рдкрдврд╝реЗрдВ рд╣рдорд╛рд░рд╛ рдкреЗрдкрд░:


тАЬрдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдм my_std::begin рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдпреЛрдЧреНрдпрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ my_std::begin рдЧреБрдВрдЬрд╛рдЗрд╢ рдХреЗ рдЕрдВрджрд░ my_std::begin , рд╕реНрдерд┐рддрд┐ рдХреБрдЫ рд╣рдж рддрдХ рдмрджрд▓ рдЬрд╛рддреА рд╣реИред рд▓реБрдХрдЕрдк рдХреЗ рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ, рдирд╛рдо рдХреА begin рд╡реИрд╢реНрд╡рд┐рдХ рдСрдмреНрдЬреЗрдХреНрдЯ my_std::begin рд╕реЗ begin ред рдХреНрдпреЛрдВрдХрд┐ рд▓реБрдХрдЕрдк рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдорд┐рд▓рд╛, рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ, рд▓реБрдХрдЕрдк рдХреЗ рджреВрд╕рд░реЗ рдЪрд░рдг рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЕрдЧрд░ my_std::begin рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ, рддреЛ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдЙрдкрдпреЛрдЧ my_std::detail::begin_fn begin; begin(a); my_std::detail::begin_fn begin; begin(a); рдмрд╕ std::begin(a); рдмрд░рд╛рдмрд░ std::begin(a); "рдФрд░ рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рджреЗрдЦрд╛ рд╣реИ, рдпрд╣ рдХрд╕реНрдЯрдо ADL рд▓реЙрдиреНрдЪ рдХрд░рддрд╛ рд╣реИред"


рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдПрдбреАрдПрд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЕрд╡рдзрд╛рд░рдгрд╛ рд╕рддреНрдпрд╛рдкрди рдХреЛ std рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдЪрдХрд░рд╛ рджреЗрдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИред


рдЕрдиреБрдХреВрд▓рди рдЕрдВрдХ рдХреИрд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рддреЗ рд╣реИрдВ?


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, "рдЕрдиреБрдХреВрд▓рди рдмрд┐рдВрджреБ рд╡рд╕реНрддреБ" (CPO) рдПрдХ рдЕрдЪреНрдЫрд╛ рдирд╛рдо рдирд╣реАрдВ рд╣реИред рдирд╛рдо рд╕реЗ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡реЗ рдХреИрд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдХреНрдпрд╛ рддрдВрддреНрд░ рд╣реБрдб рдХреЗ рдиреАрдЪреЗ рд╣реИрдВ, рд╡реЗ рдХреМрди рд╕реЗ рдХрд╛рд░реНрдп рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВ ...


рдЬреЛ рд╣рдореЗрдВ "nibloid" рд╢рдмреНрдж рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИред рдПрдХ nibloid рдПрдХ CPO рд╣реИ рдЬреЛ рдлрд╝рдВрдХреНрд╢рди X рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдЗрд╕реЗ рдХрдХреНрд╖рд╛ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди X рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдХреЛрдИ рдЙрдкрдпреБрдХреНрдд рдлрд╝реНрд░реА рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рдЕрдиреНрдпрдерд╛ рдпрд╣ рдлрд╝рдВрдХреНрд╢рди X рдХреЗ рдХреБрдЫ рдХрдордмреИрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИред


рддреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдмреЛрд▓рд┐рдб ranges::swap рдЬрдм ranges::swap рдХреЛ рдмреБрд▓рд╛рддреА рд╣реИ рддреЛ ranges::swap ranges::swap(a, b) рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ a.swap(b) рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рдРрд╕реА рдХреЛрдИ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ ADL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ swap(a, b) рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ auto tmp = std::move(a); a = std::move(b); b = std::move(tmp) рдЖрдЬрд╝рдорд╛рдПрдБ auto tmp = std::move(a); a = std::move(b); b = std::move(tmp) auto tmp = std::move(a); a = std::move(b); b = std::move(tmp) auto tmp = std::move(a); a = std::move(b); b = std::move(tmp) ред


рдкрд░рд┐рдгрд╛рдо


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


рдпрд╣ рдкреВрд░рд╛ рд▓реЗрдЦ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рддреИрдпрд╛рд░реА рдереАред


" рдореИрдВ рдмрд╕ рд╕рдм рдХреБрдЫ рд╕рдордЭ рдЧрдпрд╛, рдмрд╕ рдЗрддрдирд╛ рд╣реАред рдХреНрдпрд╛ рдЖрдк рд╕реБрдиреЗрдВрдЧреЗ ?


рдХреНрдпрд╛ рдЖрдкрдиреЗ рдХрднреА рдХреБрдЫ рджреЗрдЦрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдкрд╛рдЧрд▓ рд▓рдЧ рд░рд╣рд╛ рдерд╛, рдФрд░ рдлрд┐рд░ рдПрдХ рдЕрд▓рдЧ рд░реЛрд╢рдиреА рдореЗрдВ
рдкрд╛рдЧрд▓ рдЪреАрдЬреЗрдВ рдЙрдиреНрд╣реЗрдВ рд╕рд╛рдорд╛рдиреНрдп рджреЗрдЦрдХрд░?



рдбрд░реЛ рдорддред рдбрд░реЛ рдорддред рдореБрдЭреЗ рджрд┐рд▓ рд╕реЗ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИред рд╕рдм рдареАрдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдореИрдВрдиреЗ рдХрдИ рд╕рд╛рд▓реЛрдВ рд╕реЗ рдЗрддрдирд╛ рдЕрдЪреНрдЫрд╛ рдорд╣рд╕реВрд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рд╕рдм рдареАрдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред



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

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


All Articles