рдкреНрд░рд╛рдЧрд┐рддрд┐рд╣рд╛рд╕
рдореБрдЭреЗ C ++ рднрд╛рд╖рд╛ рдкрд╕рдВрдж рд╣реИред рдореИрдВ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдореЗрд░реА рдкрд╕рдВрджреАрджрд╛ рднрд╛рд╖рд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рдЕрдкрдиреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП .NET рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдФрд░ рдЗрд╕рдореЗрдВ рдХрдИ рд╡рд┐рдЪрд╛рд░, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдмрд╕ рдЕрджреНрднреБрдд рд╣реИрдВред рдПрдХ рдмрд╛рд░ рдЬрдм рдореИрдВ рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд╕рд╛рде рдЖрдпрд╛ - C ++ рдореЗрдВ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдФрд░ рдЧрддрд┐рд╢реАрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЗ рдХреБрдЫ рд╕рд╛рдзрдиреЛрдВ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдП? рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ C ++ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдПрдХ рд╕реАрдПрд▓рдЖрдИ рд▓рд╛рдн рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдЕрдЬреНрдЮрд╛рдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдПред рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рдЬреНрдЮрд╛рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдмреЗрд╢рдХ, рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреА рдПрдХ рдкреВрд░реА рдирдХрд▓ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд▓реЗрдЦ рдХреЗрд╡рд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдФрд░ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛ рдЬреЛ рднрд╛рд╖рд╛ рджреНрд╡рд╛рд░рд╛ рд╕реАрдзреЗ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддреЗ рд╣реИрдВред
рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди рдорд╛рдкрджрдВрдбреЛрдВ рдФрд░ рдЕрдЬреНрдЮрд╛рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдЕрдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдХрд░рдирд╛
рдмреЗрд╢рдХ, рдпрд╣ рд╕реА ++ рдХреЗ рд╕рд╛рде рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рд▓ рдХрд░рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИред рдмреЗрд╢рдХ, C ++ рдореЗрдВ C -
varargs рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдПрдХ рдЙрдкрдХрд░рдг рд╣реИ, рдФрд░ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд╣рд▓реА рдЪреАрдЬ рд╣реИ рдЬреЛ рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрддреА рд╣реИ ... рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡реЗ рдлрд┐рдЯ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░-рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдкреНрд░рдХреГрддрд┐ (рдЬреИрд╕реЗ C рд╕реЗ рдХрдИ рдЪреАрдЬреЗрдВ) рдХреЗ рдХрд╛рд░рдгред рджреВрд╕рд░реЗ, рдРрд╕реЗ рддрд░реНрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рддрд░реНрдХ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд▓рдЧрднрдЧ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣
рд╡реИрд░рдЧ рдХреЗ рд╕рд╛рде рд╕рднреА рд╕рдорд╕реНрдпрд╛рдПрдВ рдирд╣реАрдВ рд╣реИрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рдЙрдкрдХрд░рдг рдпрд╣рд╛рдВ рд╕рд╣рд╛рдпрдХ рдирд╣реАрдВ рд╣реИред
рдФрд░ рдЕрдм рдореИрдВ рдЙрди рдЙрдкрдХрд░рдгреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░реВрдВрдЧрд╛ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдореЗрд░реА рдорджрдж рдХреАред
рдПрд╕рдЯреАрдбреА :: рдХреЛрдИ рднреА
C ++ 17 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ, рднрд╛рд╖рд╛ рдореЗрдВ рдХрд┐рд╕реА рднреА рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрджреНрднреБрдд рдХрдВрдЯреЗрдирд░ рдХрдВрдЯреЗрдирд░ рд╣реИ - CLI рдореЗрдВ
System.Object рдХреЗ рд▓рд┐рдП рдХреБрдЫ рджреВрд░ рдХреА рд╕рдорд╛рдирддрд╛
:: рдХреЛрдИ рднреА ред рдпрд╣ рдХрдВрдЯреЗрдирд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреБрдЫ рднреА рд╕реНрдЯреЛрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХреИрд╕реЗ: рдХреБрд╢рд▓рддрд╛ рд╕реЗ! - рдорд╛рдирдХ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдЫреЛрдЯреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕реАрдзреЗ рдЗрд╕рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ, рдмрдбрд╝реА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЧрддрд┐рд╢реАрд▓ рдореЗрдореЛрд░реА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдЕрдирд┐рд╡рд╛рд░реНрдп рдирд╣реАрдВ рд╣реИ, рдорд╛рдЗрдХреНрд░реЛрд╕реЙрдлреНрдЯ рдиреЗ рдЕрдкрдиреЗ рд╕реА ++ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдпрд╣ рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рдЕрдЪреНрдЫреА рдЦрдмрд░ рд╣реИ)ред рдФрд░ рдХреЗрд╡рд▓ рдЗрд╕реЗ рд╕рдорд╛рдирддрд╛ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ System.Object рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рд╕рдВрдмрдВрдз ("a") рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ, рдФрд░ std :: рдХреЛрдИ рднреА рд╕рджрд╕реНрдпрддрд╛ рд╕рдВрдмрдВрдз рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИ ("a")ред рдбреЗрдЯрд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрдВрдЯреЗрдирд░ рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ
std :: type_info - RTTI рдореЗрдВ рдПрдХ рд╕рдВрдХреЗрддрдХ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдкреНрд░рдХрд╛рд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ "рдЭреВрда" рд╣реИред
рдХрдВрдЯреЗрдирд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реА рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓
<any> рдЖрд╡рдВрдЯрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред
рдХрдВрдЯреЗрдирд░ рд╕реЗ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЛ "рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓рдиреЗ" рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ
std :: any_cast () рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддрд╛ рд╣реИред
рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг:
#include <any> void any_test() { std::any obj = 5; int from_any = std::any_cast<int>(obj); }
рдпрджрд┐ рдЕрдиреБрд░реЛрдзрд┐рдд рдкреНрд░рдХрд╛рд░ рдХрдВрдЯреЗрдирд░ рдХреЗ рдЕрдВрджрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж
std :: bad_any_cast рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред
Std :: any ,
std :: bad_any_cast classes рдФрд░
std :: any_cast рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрд▓рд╛рд╡рд╛ , рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЯреЗрдореНрдкрд▓реЗрдЯ
std :: make_any рд╕рдорд╛рди
std :: make_sared ,
std ::_pair рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЕрдиреНрдп рдХрд╛рд░реНрдп рд╣реИрдВред
RTTI
рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдпрд╣ рд╕реА + + рдореЗрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╣реЛрдЧрд╛ рддрд╛рдХрд┐ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдЯрд╛рдЗрдк рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЖрдЦрд┐рд░рдХрд╛рд░, рдХрд┐рд╕реА рддрд░рд╣ рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред
C ++ рдореЗрдВ рдЖрджрд┐рдо RTTI рдХрд╛ рд╕рдорд░реНрдерди рдХрд╛рдлреА рд╕рдордп рд╕реЗ рд╣реИред рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдмрд┐рдВрджреБ рд╣реИ, рдЬреЛ рдХрд┐ рдЖрджрд┐рдо рд╣реИ - рд╣рдо рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХрдо рд╕реАрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдм рддрдХ рдХрд┐ рд╕рдЬрд╛рдП рдЧрдП рдФрд░ рдЕрдШреЛрд╖рд┐рдд рдирд╛рдо рди рд╣реЛрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЖрдорддреМрд░ рдкрд░, "RTTI" рд╢рдмреНрдж рдХрд╛ рдЙрдкрдпреЛрдЧ рдмрд╣реБрд░реВрдкрддрд╛ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣рд╛рдБ рд╣рдо рдЗрд╕ рд╢рдмреНрдж рдХрд╛ рд╡реНрдпрд╛рдкрдХ рдЕрд░реНрде рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕ рддрдереНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВрдЧреЗ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд░рдирдЯрд╛рдЗрдо рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЖрдк рдХреЗрд╡рд▓ рдкреЙрд▓рд┐рдореЛрд░реНрдлрд┐рдХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рд╕рдордп рдкрд░ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред рдЗрд╕рд▓рд┐рдП, рд░рдирдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди рдЧреИрд░-рдкреЙрд▓реАрдореЙрд░реНрдлрд┐рдХ рдкреНрд░рдХрд╛рд░ (рдЯреЛрдЯреЛрд▓реЙрдЬреА рдХреЗ рд▓рд┐рдП рдЦреЗрдж) рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рд╕рдВрднрд╡ (рдФрд░ рдЖрд╡рд╢реНрдпрдХ) рд╣реИред
RTTI рдХреЛ
std :: type_info рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╡рд░реНрдЧ
<typeinfo> рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реИред рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕рдВрджрд░реНрдн рдХреЗрд╡рд▓
рдЯрд╛рдЗрдкрд┐рдб () рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ (рдХрдо рд╕реЗ рдХрдо рдЕрднреА рдХреЗ рд▓рд┐рдП) рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕
рднрд╛рд╖рд╛ рдХреА рдПрдХ рдФрд░ рдЕрддреНрдпрдВрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рддрд╛ рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдЕрдкрдиреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рд╡рд╣ рд╣реИ рдЯреЗрдореНрдкрд▓реЗрдЯред рдпрд╣ рдЙрдкрдХрд░рдг рдХрд╛рдлреА рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдФрд░ рдЕрддреНрдпрдВрдд рдХрдард┐рди рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рдЖрдкрдХреЛ рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдПрдХ рдмрд╣реБрдд рд╡реНрдпрд╛рдкрдХ рд╡рд┐рд╖рдп рд╣реИ, рдФрд░ рдЗрд╕реЗ рд▓реЗрдЦ рдХреЗ рдврд╛рдВрдЪреЗ рдХреЗ рднреАрддрд░ рдкреНрд░рдХрдЯ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдФрд░ рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкрд╛рдардХ рд╕рдордЭрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдХреБрдЫ рдЕрд╕реНрдкрд╖реНрдЯ рдмрд┐рдВрджреБ рд╕рд╛рдордиреЗ рдЖрдПрдВрдЧреЗред
рдХреЙрд▓ рдХреЗ рдмрд╛рдж рддрд░реНрдХ рд▓рдкреЗрдЯрдирд╛
рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд▓реЗрддрд╛ рд╣реИред
рдореИрдВ рдЖрдкрдХреЛ рдПрдХ рдХреЛрдб рд╕реНрдХреЗрдЪ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдЬреЛ рдореЗрд░реЗ рдЗрд░рд╛рджреЛрдВ рдХреЛ рд╕рдордЭрд╛рдПрдЧрд╛ред
#include <Variadic_args_binder.hpp> #include <string> #include <iostream> #include <vector> #include <any> int f(int a, std::string s) { std::cout << "int: " << a << "\nstring: " << s << std::endl; return 1; } void demo() { std::vector<std::any> params; params.push_back(5); params.push_back(std::string{ "Hello, Delegates!" }); delegates::Variadic_args_binder<int(*)(int, std::string), int, std::string> binder{ f, params }; binder(); }
рдЖрдк рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдХреИрд╕реЗ рд╕рдВрднрд╡ рд╣реИ? рд╡рд░реНрдЧ рдирд╛рдо
Variadic_args_binder рдЖрдкрдХреЛ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдЙрди рддрд░реНрдХреЛрдВ рдХреЛ рдмрд╛рдВрдзрддрд╛ рд╣реИ, рдЬрдм рдЖрдк рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдпрд╣ рдХреЗрд╡рд▓ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рдмрд╛рдЗрдВрдбрд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ!
рдЗрд╕рд▓рд┐рдП рдпрд╣ рдмрд╛рд╣рд░ рджрд┐рдЦрддрд╛ рд╣реИред
рдпрджрд┐ рддреБрд░рдВрдд, рдмрд┐рдирд╛ рд╕реЛрдЪреЗ-рд╕рдордЭреЗ, рдпрд╣ рдзрд╛рд░рдгрд╛ рдмрдирд╛ рд▓реЗрдВ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдХрдИ
Variadic_args_binder рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛рдУрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдорди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ рдпрджрд┐ рдЕрд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдФрд░ рдпрд╣рд╛рдБ рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ: рддрд░реНрдХ, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЛ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреН, рдЕрдВрдд рдореЗрдВ рд╕рдВрдХрд▓рдХ рдХреЗ рд▓рд┐рдП, рдХреЙрд▓ рдХреЛрдб рдХреЛ рдЗрд╕ рдкрд░ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
fun_ptr(param1, param2, тАж, paramN);
рдпрд╣ C ++ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╕рдм рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реИред
рдХреЗрд╡рд▓ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЬрд╛рджреВ рдЗрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ!
рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдмрдирд╛рдирд╛ рд╣реИ рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╕реНрддрд░ рдкрд░ рддрд░реНрдХреЛрдВ рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП,
_Tagged_args_binder рд╡рд░реНрдЧ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:
namespace delegates::impl { template <typename Func_type, typename... T> class _Tagged_args_binder; }
рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ "рдЯреНрд░рд╛рдВрд╕рдлрд░" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░
рдмрдирд╛рдПрдВрдЧреЗ ,
Type_pack_tag (рдпрд╣ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рдпрд╣ рдЬрд▓реНрдж рд╣реА рдмрди рдЬрд╛рдПрдЧрд╛):
template <typename... T> struct Type_pack_tag { };
рдЕрдм рд╣рдо
_Tagged_args_binder рд╡рд░реНрдЧ рдХреЗ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдмрдирд╛рддреЗ рд╣реИрдВред
рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛рдУрдВ
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдЕрдирдВрдд рди рд╣реЛ, рд╕реАрдорд╛ рдорд╛рдорд▓реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╣реИрдВред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХреЗрд╡рд▓ рдЧреИрд░-рд╕рдВрджрд░реНрдн рдкреНрд░рдХрд╛рд░ рдФрд░ рд╕рдВрджрд░реНрдн рд╕рдВрджрд░реНрдн рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рд╣рд╡рд╛рд▓рд╛ рджреВрдВрдЧрд╛ред
рд╕реАрдзреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛:
template <typename Func_type, typename T1, typename... Types_to_construct> class _Tagged_args_binder<Func_type, Type_pack_tag<T1, Types_to_construct...>, Type_pack_tag<>> { public: static_assert(!std::is_same_v<void, T1>, "Void argument is not allowed"); using Ret_type = std::invoke_result_t<Func_type, T1, Types_to_construct...>; _Tagged_args_binder(Func_type func, std::vector<std::any>& args) : ap_arg{ std::move(unihold::reference_any_cast<T1>(args.at(0))) }, ap_caller_part{ func, args } { } auto operator()() { if constexpr(std::is_same_v<void, Ret_type>) { ap_caller_part(std::move(ap_arg)); return; } else { return std::forward<Ret_type>(ap_caller_part(std::move(ap_arg))); } } auto operator()() const { if constexpr (std::is_same_v<void, Ret_type>) { ap_caller_part(std::move(ap_arg)); return; } else { return std::forward<Ret_type>(ap_caller_part(std::move(ap_arg))); } } private: _Tagged_args_binder<Func_type, Type_pack_tag<Types_to_construct...>, Type_pack_tag<T1>> ap_caller_part; T1 ap_arg; };
Ap_arg рдХреЙрд▓ рдХрд╛ рдкрд╣рд▓рд╛ рддрд░реНрдХ рдФрд░ рдмрд╛рдХреА рдкреБрдирд░рд╛рд╡рд░реНрддреА
ap_caller_part рдСрдмреНрдЬреЗрдХреНрдЯ рдпрд╣рд╛рдВ
рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИ ред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐
рдЯреА 1 рдкреНрд░рдХрд╛рд░ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдкрд╣рд▓реЗ рдкреИрдХреЗрдЯ рд╕реЗ "рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд" рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ "рдкреВрдВрдЫ" рдореЗрдВ рджреВрд╕рд░реЗ рдирдВрдмрд░ рдкрд░ рд╣реЛрддрд╛ рд╣реИред
рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛:
template <typename Func_type, typename T1, typename... Types_to_construct> class _Tagged_args_binder<Func_type, Type_pack_tag<T1&&, Types_to_construct...>, Type_pack_tag<>> { using move_ref_T1 = std::add_rvalue_reference_t<std::remove_reference_t<T1>>; public: using Ret_type = std::invoke_result_t<Func_type, move_ref_T1, Types_to_construct>; _Tagged_args_binder(Func_type func, std::vector<std::any>& args) : ap_arg{ std::move(unihold::reference_any_cast<T1>(args.at(0))) }, ap_caller_part{ func, args } { } auto operator()() { if constexpr (std::is_same_v<void, Ret_type>) { ap_caller_part(std::move(unihold::reference_any_cast<T1>(ap_arg))); } else { return std::forward<Ret_type>(ap_caller_part(std::move(unihold::reference_any_cast<T1>(ap_arg)))); } } auto operator()() const { if constexpr (std::is_same_v<void, Ret_type>) { ap_caller_part(std::move(unihold::reference_any_cast<T1>(ap_arg))); } else { return std::forward<Ret_type>(ap_caller_part(std::move(unihold::reference_any_cast<T1>(ap_arg)))); } } private: _Tagged_args_binder<Func_type, Type_pack_tag<Types_to_construct...>, Type_pack_tag<move_ref_T1>> ap_caller_part; std::any ap_arg; };
рдЯреЗрдореНрдкрд▓реЗрдЯ "рд░рд╛рдЗрдЯ-рд╣реИрдВрдбреЗрдб" рд▓рд┐рдВрдХ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд░рд╛рдЗрдЯ-рд╣реИрдВрдб рдЕрд░реНрде рдирд╣реАрдВ рд╣реИрдВред рдпреЗ рддрдерд╛рдХрдерд┐рдд "рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рд▓рд┐рдВрдХ" рд╣реИрдВ, рдЬреЛ рдХрд┐
T1 рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░,
T1 & , рдпрд╛
T1 && рдмрди рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛: рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЪреВрдВрдХрд┐ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛рдУрдВ рдХреЛ рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╣ рдХрд╛рдлреА рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдирд╣реАрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рдмрддрд╛рдП рдЧрдП рдХрд╛рд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП) рдФрд░ рдЧреИрд░-рд╕рдВрджрд░реНрдн рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП, рдЬрдм рдЖрдк рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рддреНрд╡рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рднрд▓реЗ рд╣реА рдпрд╣ рдПрдХ рджрд╛рд╣рд┐рдиреЗ рд╣рд╛рде рдХреА рдХрдбрд╝реА рд╣реЛ; рджреВрд╕рд░реА рдмрд╛рдд,
T1 рдкреНрд░рдХрд╛рд░ рдХреЛ рдкреИрдХреЗрдЬ рд╕реЗ рдкреИрдХреЗрдЬ рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП,
Move_ref_T1 рдХреЗ рд╕рд╣реА рд╕рдВрд╕реНрдХрд░рдг рдХрд╛
рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ , рдЬрд┐рд╕реЗ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкреНрд░рддрд┐рджреНрд╡рдВрджреНрд╡рд┐рддрд╛ рд▓рд┐рдВрдХ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдЙрд╕реА рддрд░рд╣ рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ, рдЖрд╡рд╢реНрдпрдХ рд╕реБрдзрд╛рд░ рдХреЗ рд╕рд╛рдеред
рдЕрдВрддрд┐рдо рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛
template <typename Func_type, typename... Param_type> class _Tagged_args_binder<Func_type, Type_pack_tag<>, Type_pack_tag<Param_type...>> { public: using Ret_type = std::invoke_result_t<Func_type, Param_type...>; inline _Tagged_args_binder(Func_type func, std::vector<std::any>& args) : ap_func{ func } { } inline auto operator()(Param_type... param) { if constexpr(std::is_same_v<void, decltype(ap_func(std::forward<Param_type>(param)...))>) { ap_func(std::forward<Param_type>(param)...); return; } else { return std::forward<Ret_type>(ap_func(std::forward<Param_type>(param)...)); } } inline auto operator()(Param_type... param) const { if constexpr(std::is_same_v<void, Ret_type>) { ap_func(param...); return; } else { return std::forward<Ret_type>(ap_func(param...)); } } private: Func_type ap_func; };
рдпрд╣ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд╕реНрддреБ рдХреЗ рднрдВрдбрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдФрд░, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕рдХреЗ рдКрдкрд░ рдПрдХ рдЖрд╡рд░рдг рд╣реИред рдпрд╣ рдЕрдВрддрд┐рдо рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХрд╛рд░ рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐
Type_pack_tag рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣рд╛рдБ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рднреА рдкреИрд░рд╛рдореАрдЯрд░ рдкреНрд░рдХрд╛рд░ рдЕрдм рдмрд╛рдПрдВ рдкреИрдХреЗрдЬ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡реЗ рд╕рднреА рд╕рдВрд╕рд╛рдзрд┐рдд рдФрд░ рдкреИрдХ рдХрд┐рдП рдЧрдП рд╣реИрдВред
рдЕрдм, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐
Type_pack_tag рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХреНрдпреЛрдВ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐, рднрд╛рд╖рд╛ рджреЛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрдХреЗрдЬреЛрдВ рдХреЛ рдПрдХ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧреА, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣:
template <typename Func_type, typename T1, typename... Types_to_construct, typename... Param_type> class _Tagged_args_binder<Func_type, T1, Types_to_construct..., Param_type...> { };
рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рджреЛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЕрдВрджрд░ рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреИрдХреЗрдЬреЛрдВ рдореЗрдВ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рдЖрдкрдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рдЙрди рд▓реЛрдЧреЛрдВ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЕрднреА рддрдХ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВред
рдЗрдВрдЯрд░рдореАрдбрд┐рдПрдЯ рд╕реНрдкреЗрд╢рд▓рд╛рдЗрдЬреЗрд╢рди
рдордзреНрдпрд╡рд░реНрддреА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╕реЗ, рдореИрдВ рдЕрдВрдд рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рджреВрдВрдЧрд╛, рдлрд┐рд░ рд╕реЗ, рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП, рдмрд╛рдХреА рдЙрдкрдорд╛ рд╕реЗ рд╣реИ:
template <typename Func_type, typename T1, typename... Types_to_construct, typename... Param_type> class _Tagged_args_binder<Func_type, Type_pack_tag<T1, Types_to_construct...>, Type_pack_tag<Param_type...>> { public: using Ret_type = std::invoke_result_t<Func_type, Param_type..., T1, Types_to_construct...>; static_assert(!std::is_same_v<void, T1>, "Void argument is not allowed"); inline _Tagged_args_binder(Func_type func, std::vector<std::any>& args) : ap_arg{ std::move(unihold::reference_any_cast<T1>(args.at(sizeof...(Param_type)))) }, ap_caller_part{ func, args } { } inline auto operator()(Param_type... param) { if constexpr (std::is_same_v<void, Ret_type>) { ap_caller_part(std::forward<Param_type>(param)..., std::move(ap_arg)); return; } else { return std::forward<Ret_type>(ap_caller_part(std::forward<Param_type>(param)..., std::move(ap_arg))); } } inline auto operator()(Param_type... param) const { if constexpr (std::is_same_v<void, Ret_type>) { ap_caller_part(std::forward<Param_type>(param)..., std::move(ap_arg)); } else { return std::forward<Ret_type>(ap_caller_part(std::forward<Param_type>(param)..., std::move(ap_arg))); } } private: _Tagged_args_binder<Func_type, Type_pack_tag<Types_to_construct...>, Type_pack_tag<Param_type..., T1>> ap_caller_part; T1 ap_arg; };
рдЗрд╕ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдкрд╣рд▓реЗ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд┐рд╕реА рднреА рддрд░реНрдХ рдХреЛ рдкреИрдХ рдХрд░рдирд╛ рд╣реИред
рдмрд╛рдЗрдВрдбрд░ рдХреНрд▓рд╛рд╕
_Tagged_args_binder рд╡рд░реНрдЧ рдкреНрд░рддреНрдпрдХреНрд╖ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рдкреНрд░реЗрдд рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕реЗ рдореИрдВ рдЗрд╕рдХреЗ рдирд╛рдо рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдПрдХ рдПрдХрд▓ рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рдХреЗ рд╕рд╛рде рдЬреЛрд░ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдЗрд╕рд▓рд┐рдП, рдореИрдВ рдПрдХ рдЫреЛрдЯреЗ рд╡рд░реНрдЧ рдХрд╛ рдХреЛрдб рджреВрдВрдЧрд╛, рдЬреЛ рдХрд┐ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдмрджрд╕реВрд░рдд рдФрд░ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдХреЗ рд▓рд┐рдП "рдЗрдВрдЯрд░рдлрд╝реЗрд╕" рдХрд╛ рдПрдХ рдкреНрд░рдХрд╛рд░ рд╣реИ (рдЬреЛ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдмрд▓реНрдХрд┐ рдЕрд╕рд╛рдорд╛рдиреНрдп рд╕реА ++ рдЯреНрд░рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЗрд╕реЗ рдХреБрдЫ рдЖрдХрд░реНрд╖рдг рджреЗрддрд╛ рд╣реИ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ):
namespace cutecpplib::delegates { template <typename Functor_type, typename... Param_type> class Variadic_args_binder { using binder_type = impl::_Tagged_args_binder<Functor_type, Type_pack_tag<Param_type...>, Type_pack_tag<>>; public: using Ret_type = std::invoke_result_t<binder_type>; inline Variadic_args_binder(Functor_type function, Param_type... param) : ap_tagged_binder{ function, param... } { } inline Variadic_args_binder(Functor_type function, std::vector<std::any>& args) : ap_tagged_binder{ function, args } { } inline auto operator()() { return ap_tagged_binder(); } inline auto operator()() const { return ap_tagged_binder(); } private: binder_type ap_tagged_binder; }; }
Unihold рдХрдиреНрд╡реЗрдВрд╢рди - std рдХреЗ рдЕрдВрджрд░ рдкрд╛рд╕рд┐рдВрдЧ рд▓рд┐рдВрдХ :: рдХреЛрдИ рднреА
рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рдиреЗ рджреЗрдЦрд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХреЛрдб
unihold :: reference_any_cast () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди, рд╕рд╛рде рд╣реА рдЗрд╕рдХреЗ рдПрдирд╛рд▓реЙрдЧ
рдпреВрдиреАрд╣реЛрд▓реНрдб :: рдкреЙрдЗрдВрдЯрд░_рдиреНрдп_рдХрд╛рд╕реНрдЯ () , рдХреЛ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕рдордЭреМрддреЗ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рддрд░реНрдХреЛрдВ рдХреЛ рдкреЙрдЗрдВрдЯрд░ рджреНрд╡рд╛рд░рд╛
std :: any рджреНрд╡рд╛рд░рд╛ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд╕рдВрджрд░реНрдн_рдпрд╛_рдХрд╛рд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрд╢рд╛ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддрд╛ рд╣реИ, рдЪрд╛рд╣реЗ рд╡рд╣ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛ рдпрд╛ рдХреЗрд╡рд▓ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╣реЛред рдпрджрд┐
std :: рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдореЗрдВ рдХреЛрдИ рд╡рд╕реНрддреБ рд╕рдорд╛рд╣рд┐рдд рд╣реИ, рддреЛ рдЗрд╕ рд╡рд╕реНрддреБ рдХрд╛ рдПрдХ рд╕рдВрджрд░реНрдн рдХрдВрдЯреЗрдирд░ рдХреЗ рдЕрдВрджрд░ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИ; рдпрджрд┐ рдЗрд╕рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкреЙрдЗрдВрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдЗрдВрдЧрд┐рдд рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдПрдХ рд╕рдВрджрд░реНрдн рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП, рдирд┐рд░рдВрддрд░
std :: рдХрд┐рд╕реА рднреА рдФрд░ рдЕрддрд┐рднрд╛рд░рд┐рдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХрдВрдЯреЗрдирд░
std :: рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ рдХрд╛ рдорд╛рд▓рд┐рдХ рд╣реИ рдпрд╛ рдХреЗрд╡рд▓ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рд╣реИред
рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд┐рдП рдЧрдП рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд┐рд╢реЗрд╖ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреИрд╕реЗ рд╕реА ++ рдкреНрд░рдХрд╛рд░ рд░реВрдкрд╛рдВрддрд░рдг рдФрд░ рд╕рдорд╛рди рдЯреЗрдореНрдкрд▓реЗрдЯ рдлрд╝рдВрдХреНрд╢рдиред
рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб:
template <typename T> std::remove_reference_t<T>& unihold::reference_any_cast(std::any& wrapper) { bool result; return reference_any_cast<T>(wrapper, result); } template <typename T> const std::remove_reference_t<T>& unihold::reference_any_cast(const std::any& wrapper) { bool result; return reference_any_cast<T>(wrapper, result); } template <typename T> std::remove_reference_t<T>& unihold::reference_any_cast(std::any& wrapper, bool& is_owner) { auto ptr = pointer_any_cast<T>(&wrapper, is_owner); if (!ptr) throw std::bad_any_cast{ }; return *ptr; } template <typename T> const std::remove_reference_t<T>& unihold::reference_any_cast(const std::any& wrapper, bool& is_owner) { auto ptr = pointer_any_cast<T>(&wrapper, is_owner); if (!ptr) throw std::bad_any_cast{ }; return *ptr; } template <typename T> std::remove_reference_t<T>* unihold::pointer_any_cast(std::any* wrapper, bool& is_owner) { using namespace std; using NR_T = remove_reference_t<T>;
рдирд┐рд╖реНрдХрд░реНрд╖
рдореИрдВрдиреЗ C ++ рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХрд╛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреАред рдЗрд╕рдХреЗ рдмрд╛рдж, рдпрд╣ C ++ рдбреЗрд▓реАрдЧреЗрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдЖрдзрд╛рд░ рдмрдиреЗрдЧрд╛ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рдореВрд▓ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛, рдЕрд░реНрдерд╛рддреН рдмрд╣реБрд░реВрдкреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреЛ рд▓рд┐рдЦ рджрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдб рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рдХреБрдЫ рдЕрд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдЕрднреА рднреА рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ)ред рдирд┐рдХрдЯ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореИрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкрд░ рдХрд╛рдо рдЦрддреНрдо рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдпрд╣ рдмрддрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдореИрдВрдиреЗ рд╕реА ++ рдореЗрдВ рдмрд╛рдХреА рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред
PS RTTI рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред