рдлрдВрдХреНрд╢рди рдУрд╡рд░рд▓реЛрдбрд┐рдВрдЧ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ C ++ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреА рдорджрдж рдХрд░реЗрдВ

рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, C ++ рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдЕрддрд┐рднрд╛рд░рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЪрдпрди рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬреЛ рдорд╛рдирд╡ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╣реИ - рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ:

void f(int i){} void f(string s){} vector<int> int_c = { 1, 2, 3, 4, 5 }; vector<string> string_c = { "Sic" ,"transit" ,"gloria" ,"mundi" }; for_each(begin(int_c), end(int_c), f);//error C2672: "for_each":      

рд╕рдорд╕реНрдпрд╛ рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдореЗрдВ f рдХреЗ рд▓рд┐рдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреА рдХрдореА рд╣реИ, рдЬрд┐рд╕ рдкрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдЕрдзрд┐рднрд╛рд░ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рддрдереНрдп рдХрд┐ рдмрд╣реБрдд рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ for_each рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕рдВрдХрд▓рдХ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорд╛рдпрдиреЗ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИред

рдЖрдк рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рдХрдИ "рд▓рд▓рд╛рдЯ" рддрд░реАрдХреЗ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ:

1) рд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдХреЛ рдХрд╛рд╕реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП static_cast <> () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред

рд╣рдо рд╕реВрдЪрдХ рдХреЛ f (v i) рд╢реВрдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд╕реНрдЯ рдХрд░рддреЗ рд╣реИрдВ:

 std::for_each(begin(int_c), end(int_c), static_cast<void (*)(int)>(&f)); 

рд╣рдо рд╕реВрдЪрдХ рдХреЛ рд╢реВрдиреНрдп (рд╕реНрдЯреНрд░рд┐рдВрдЧ i) рд╢реВрдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓реЗ рдЧрдП:

 std::for_each(begin(string_c), end(string_c), static_cast<void (*)(string)>(&f)); 

2) рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдЙрдирдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ред

рд╣рдо рд╢реВрдиреНрдп f (int i) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

  void (*fp_int)(int) = &f; for_each(begin(int_c), end(int_c), fp_int); 

рд╣рдо рд╢реВрдиреНрдп f (рд╕реНрдЯреНрд░рд┐рдВрдЧ i) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

 void (*fp_string)(string) = &f; for_each(begin(string_c), end(string_c), fp_string); 

3) for_each рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдмрдирд╛рдирд╛:

рд╣рдо рд╢реВрдиреНрдп f (int i) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

 std::for_each<vector<int>::const_iterator, void(*)(int) >(int_c.begin(), int_c.end(), f); 

рд╣рдо рд╢реВрдиреНрдп f (рд╕реНрдЯреНрд░рд┐рдВрдЧ i) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ:

 std::for_each<vector<string>::const_iterator, void(*)(string) >(string_c.begin(), string_c.end(), f); 

рдпрд╛ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ:

 std::for_each<decltype(int_c.begin()), void(*)(int) >(int_c.begin(), int_c.end(), f); std::for_each<decltype(string_c.begin()), void(*)(string) >(string_c.begin(), string_c.end(), f); 

рдКрдкрд░ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рддрд░реАрдХреЗ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдирд╣реАрдВ рд╣реИрдВ рдФрд░ рдХреЙрд▓рд┐рдВрдЧ рдкрдХреНрд╖ рдкрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди f рдХреЗ рдКрдкрд░ рдПрдХ рдкрддрд▓рд╛ рд╢реЗрд▓ рдмрдирд╛рдпрд╛ рдЬрд╛рдП рдЬреЛ рдлрд╝рдВрдХреНрд╢рди f рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдЙрдиреНрд╣реЗрдВ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИред

рд╕рдВрднрд╛рд╡рдирд╛рдУрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИ:

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

рдЪрд░рдг рджрд░ рдЪрд░рдг рд╣рдо рдРрд╕реЗ рд╢реЗрд▓ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗред рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдЕрдЪреНрдЫреА рдиреАрдВрд╡ рд╣реИред рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ C ++ 11 рдорд╛рдирдХ рдХреЗ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде, рдЗрд╕реЗ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

 for_each(begin(int_c), end(int_c), [](int a) { return f(a); }); for_each(begin(string_c), end(string_c), [](string a) { return f(a); }); 

рдпрд╛ рдШреЛрд╖рдгрд╛рдкрддреНрд░ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░:

 for_each(begin(int_c), end(int_c), [](decltype(*int_c.begin()) a) { return f(a); }); for_each(begin(string_c), end(string_c), [](decltype(*string_c.begin()) a) { return f(a); }); 

рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ C ++ 14 рдорд╛рдирдХ рдХреЗ рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрд░реВрдкреА рд▓реИрдВрдмрдбрд╛ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╛рдзрд╛рди рд╣реИ:

 auto l = [](auto a) { return f(a); }; for_each(begin(int_c), end(int_c), l); for_each(begin(string_c), end(string_c), l); 

рддреЛ, рд╣рдо рдлрдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ f рд╕реЗ рд▓реИрдореНрдмрдбрд╛ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо рдЗрд╕ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде f рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ: рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ - рдХреНрдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдПрдл рдорд╛рди рдпрд╛ рд╕рдВрджрд░реНрдн рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ? рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕рд╣реА рдЧрд┐рдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

 auto l = [](auto&& a) { return f(std::forward<decltype(a)>(a)); }; for_each(begin(int_c), end(int_c), l); for_each(begin(string_c), end(string_c), l); 

рдкрд░рдлреЗрдХреНрдЯ рдЯреНрд░рд╛рдВрд╕рдорд┐рд╢рди (рдкрд░рдлреЗрдХреНрдЯ рдлреЙрд░рд╡рд░реНрдбрд┐рдВрдЧ) рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рдореЗрдпрд░реНрд╕ [1] рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЙрд╕реА рд╕рд╛рдордЧреНрд░реА рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рдХрд╛ рдПрдХ рдФрд░ рдЕрдзрд┐рдХ рд╕рдордЭрдиреЗ рдпреЛрдЧреНрдп (рдореЗрд░реЗ рд▓рд┐рдП, рд╡реИрд╕реЗ) рд╕рдВрд╕реНрдХрд░рдг рд▓реЗрдЦ [2] рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрдиреБрд╡рд╛рдж рд╣реИрдмреЗ [3] рдкрд░ рд╣реИред

рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдХреА рдЕрдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рд▓рдВрдмреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╡реИрд░ рд╕рдХреНрд╖рдо рдФрд░ рдХреЙрд▓ std рдХреЗ рд░реВрдк рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ :: f рдХреЗ рд▓рд┐рдП рдкрд╛рд░рд┐рдд рдкреНрд░рддреНрдпреЗрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗред

  auto l = [](auto&&... a) { return f(std::forward<decltype(a)>(a)...); }; 

рд╣рдо рд╕рдВрдХрд▓рдХ рд╕рдордп рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдиреЛрдЗрд╕реЗрдкреНрдЯ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ [4] рдФрд░ рдиреЙрдЗрд╕реЗрдкреНрдЯ рдСрдкрд░реЗрдЯрд░ рдХреЛ [5] рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди f рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХ рджреЗрдЧрд╛ [6]ред

  auto l = [](auto&&... a) \ noexcept(noexcept(f(std::forward<decltype(a)>(a)...)))\ { return f(std::forward<decltype(a)>(a)...); }; 

рдирд┐рд░реНрдорд┐рдд рд▓рдВрдмреЛрджрд░ рдХреЗ рд▓рд┐рдП рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдЯрд╛рдЗрдк рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рдЬреЛрдбрд╝реЗрдВред

  auto l = [](auto&&... a) \ noexcept(noexcept(f(std::forward<decltype(a)>(a)...)))\ -> decltype(f(std::forward<decltype(a)>(a)...))\ { return f(std::forward<decltype(a)>(a)...); }; 

рдпрджрд┐ рдЯреНрд░рд┐рдкрд▓ рдХреЛрдб рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИ рдФрд░ рд╣рдо рдореИрдХреНрд░реЛрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдореЗрдВ рд╕рдВрдХреЛрдЪ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ - рддреЛ рдЖрдк рдХреЙрд▓рд┐рдВрдЧ рдкрдХреНрд╖ рдкрд░ рдЖрдХрд╛рд░ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 #define LIFT(foo) \ [](auto&&... x) \ noexcept(noexcept(foo(std::forward<decltype(x)>(x)...))) \ -> decltype(foo(std::forward<decltype(x)>(x)...)) \ { return foo(std::forward<decltype(x)>(x)...); } 

рдирддреАрдЬрддрди, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╢реЗрд▓ рд╣реИ рдЬреЛ рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЛ рдПрдХ рдЕрдзрд┐рднрд╛рд░рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред

 for_each(begin(int_c), end(int_c), LIFT(f)); for_each(begin(string_c), end(string_c), LIFT(f)); 

[рез] рдПрд╕ред рдореЗрдпрд░реНрд╕ "рдкреНрд░рднрд╛рд╡реА рдЖрдзреБрдирд┐рдХ рд╕реА ++" рдЖрдЗрдЯрдо реирек: рд░реВрд╡рд▓ рд╕рдВрджрд░реНрднреЛрдВ рд╕реЗ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд╕рдВрджрд░реНрднреЛрдВ рдХрд╛ рднреЗрдж рдХрд░реЗрдВред
[реи] eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c
[рей] habr.com/en/post/242639
[рек] en.cppreference.com/w/cpp/language/noexcept_spec
[рел] en.cppreference.com/w/cpp/language/noexcept
[рем] habr.com/en/post/164221
[[] Www.fluentcpp.com/2017/08/01/overloaded-functions-stl
[[] Www.youtube.com/watch?v=I3T4lePH-yA

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


All Articles