рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдореБрдЭреЗ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдкрдбрд╝рд╛ рдЬрд┐рд╕рдореЗрдВ рдорд╛рдирдХ рдПрд╕рдЯреАрдПрд▓ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдордирдорд╛рдиреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ :: рдХреЛрдИ рднреА рдкреНрд░рдХрд╛рд░ред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
void foo (std::vector<boost::any>& args) {
рдкрд┐рдЫрд▓реЗ рдбреЗрд╡рд▓рдкрд░ рдмрд╣реБрдд рд╕рдЯреАрдХ рдирд╣реАрдВ рдерд╛ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░, рдмреВрд╕реНрдЯ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ :: рдХреЛрдИ рднреА рдореВрд▓ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреА рдзрд╛рд░рдгрд╛ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдерд╛, рдЕрд░реНрдерд╛рдд, рдЕрдЧрд░ рд░реВрдкрд╛рдВрддрд░рдг рдХрд╛ рд░реВрдкрд╛рдВрддрд░рдг :: any_cast рдкрд╛рд╕ рдирд╣реАрдВ рд╣реБрдЖ, рддреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдпрд╣ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╡рд┐рдзрд┐ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ рдФрд░ рдЗрд╕ рдХрд╛рд░реНрдп рддрдХрдиреАрдХ рдХреЗ рдЙрджрд╛рд╣рд░рдг
рдпрд╣рд╛рдВ рдорд┐рд▓ рд╕рдХрддреЗ
рд╣реИрдВ ред
рд╣рд╛рд▓рд╛рдБрдХрд┐, рдореИрдВ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред
рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ std :: рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рд╣реЛрдВ:
рд╢реЙрд░реНрдЯ, рдЗрдВрдЯ, рдлреНрд▓реЛрдЯ, рдбрдмрд▓, рдФрд░ рдПрдХ рдлрдВрдХреНрд╢рди рд╣реИ
double sum (std::vector<boost::any>& args) { }
рдХрдВрдЯреЗрдирд░ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рд╡рд╛рд▓реЗ :: any_cast <double> рдХреЛ рдкрд╛рд░рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд░рд╛рд╢рд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред
рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдмрдврд╝рд╛рд╡рд╛ :: any_cast рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ
template<typename ValueType> ValueType * any_cast(any * operand) {
рдпрджрд┐ рдореВрд▓ рдкреНрд░рдХрд╛рд░ рдХрд╛ type_info рдорд╛рди рдФрд░ рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рд╕реЗ рд░реВрдкрд╛рдВрддрд░рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╡рд╣ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ 0. рд▓реМрдЯрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди, рд╕рд╛рдорд╛рдиреНрдп рдХрд╛рд░реНрдп рдореЗрдВ, рдпреЛрдЧ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рд▓реМрдЯрдХрд░, рд╣рдо рдЦреБрдж рдХреЛ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рдХрд╛рдлреА рд╕рдХреНрд╖рдо рд╣реЛрддреЗ рд╣реИрдВ
double value=1+2L+3.0F+4.0;
рдЗрд╕ рдкреНрд░рдХрд╛рд░ int, long, float рдФрд░ double рдХреЛ рдЬреЛрдбрд╝рдирд╛ред рд╣рдо рд╕рдо рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рд╕рдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдпрд╣ рд╣реИ рдХрд┐, рдЬрдм рдкреНрд░реЛрд╕реЗрд╢рди :: рдХрд┐рд╕реА рднреА рд╡реИрд▓реНрдпреВ рдХреЛ рдкреНрд░реЛрд╕реЗрд╕реНрдб рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдпрд╣ рдХрд╣рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ: "рдЕрд░реЗ, рдлрдВрдХреНрд╢рди 'рд╕реНрдорде рдХрд╛рд╕реНрдЯ (рдХреЛрдИ рднреА)', рдпрджрд┐ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдХрд┐рд╕реА рднреА рд╕реНрдорд╛рдЯ рдЯрд╛рдЗрдк рдореЗрдВ рдХрдиреНрд╡рд░реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред" рдФрд░ рдХрд╛рд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рд╕реЗ Smth рдХреЛ рдЬрдиреНрдо рджреЗ рд╕рдХрддрд╛ рд╣реИ, рд╣рдореЗрдВ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдЪрд╛рд╣рд┐рдПред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдо рдЙрди рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрд╕рд╛рдиреА рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдмрдврд╝рд╛рд╡рд╛ рджреЗрдВ :: mpl рдкреБрд╕реНрддрдХрд╛рд▓рдп рдФрд░ рд╣рдореЗрдВ рд╡рд╣рд╛рдВ рдЖрд╡рд╢реНрдпрдХ
рдкреНрд░рдХрд╛рд░ рдХреЗ рджреГрд╢реНрдпреЛрдВ рдХреА
рдЕрд╡рдзрд╛рд░рдгрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВред
рдЕрдм рд╣рдореЗрдВ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдЯрд╛рдЗрдк рдХрдиреНрд╡рд░реНрдЯрд░ рдХреНрд▓рд╛рд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: any_cast, рд╕рд╛рде рд╣реА рдЯрд╛рдЗрдк рдХрдиреНрд╡рд░реНрдЯрд░ рдХреНрд▓рд╛рд╕, рдЬреЛ
- рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо ToType рдореЗрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ
- рдпрд╣ рд╕рдВрдЧрдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░реЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЖрд╡рд╢реНрдпрдХ ToType рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд░реВрдкрд╛рдВрддрд░рдг рд╕рдВрднрд╡ рд╣реИ
- рдмрдврд╝рд╛рд╡рд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ :: рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ, рдпрд╣ рд╣рдореЗрдВ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдкреНрд░рдХрд╛рд░ рдХрдирд╡рд░реНрдЯрд░ рд▓реМрдЯрд╛рдПрдЧрд╛ред
рдХрдирд╡рд░реНрдЯрд░ рд╡рд░реНрдЧ рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ type_info рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рднреА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рд╡рд╣ рд░реВрдкрд╛рдВрддрд░рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИ:
template<class ToType> class Converter { public: virtual ~Converter {} virtual ToType cast(const boost::any& arg) = 0; explicit Converter(const type_info* info) : m_info(info) { } const type_info& type() { return *m_info; } private: const type_info* m_info; };
рдХрд╛рд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд┐рд╢реБрджреНрдз рд░реВрдк рд╕реЗ рдЖрднрд╛рд╕реА рдШреЛрд╖рд┐рдд рдХреНрдпреЛрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрд╣ рдереЛрдбрд╝рд╛ рдХрдо рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рдЕрдм рд╣рдо рд╡рд░реНрдЧ рдкреНрд░реЗрд╖рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:
template<class CompatibleTypes, class ToType> class TypesDispatcher { std::vector<Converter<ToType>* > converters; struct wrapper {
рдбрд┐рд╕реНрдкреИрдЪрд░ рд╡рд░реНрдЧ рдХреЛ рд╡реИрдз рдХрдореНрдкреЗрдЯрд┐рдмрд▓рдЯреЗрдкреНрд╕ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рджреНрд╡рд╛рд░рд╛ рдФрд░ рдЬрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдЯреВрдЯрд╛рдЗрдк рд░реВрдкрд╛рдВрддрд░рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреЗ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рдЪрд╛рд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХрдВрдЯреЗрдирд░ рдХрдирд╡рд░реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рдХрд╛ рдПрдХ рдХрдВрдЯреЗрдирд░ рд░рдЦрддрд╛ рд╣реИред рд╣рдо рд╕рдВрдЧрдд рдХрдирд╡рд░реНрдЯрд░ рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдХрдирд╡рд░реНрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХрдирд╡рд░реНрдЯрд░ рд╕реЗ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдХрд╛рд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗ:
template <class FromType, class ToType> class TypeConverter : public Converter<ToType> { public: TypeConverter() : Converter(&typeid(FromType)) { } virtual ToType cast(const boost::any& arg) { return static_cast<ToType>(*boost::any_cast<FromType>(&arg)); } };
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрдореНрдкреИрдЯрд┐рдмрд▓рдЯреЗрдкреНрд╕ рдХреЗ рд▓рд┐рдП рдХрдирд╡рд░реНрдЯрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рд╣реИ, рд╕рд╛рде рд╣реА рд╕рд╛рде рдЧреЗрдЯрдХреЙрд░реНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╣реИред
рдХрдореНрдкреЗрдЯрд┐рдмрд▓рдЯреЗрдкреНрд╕ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реВрдЪреА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдордиреЗ рдмрдврд╝рд╛рд╡рд╛ рджрд┐рдпрд╛ :: mpl :: for_each, рдЬреЛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдПрдХ рдлрдВрдХреНрд╢рди рд▓реЗрддрд╛ рд╣реИ рдЬреЛ рд░рди рдЯрд╛рдЗрдо рдореЗрдВ рд╕реВрдЪреА рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рддреНрд╡рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
GetConverter рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рд░рд▓ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИ:
Converter<ToType>* getConverter(const boost::any& arg) { std::vector<Converter<ToType>* >::const_iterator it = converters.begin(); while(it != converters.end() ) { Converter<ToType>* converter = *it; if(converter->type() == arg.type()) return converter; ++it; } return 0; }
рд╡рд╣ рд╕рдм рд╣реИред рдЕрдм рд╣рдо рдХреБрдЫ рдРрд╕рд╛ рд▓рд┐рдЦ тАЛтАЛрд╕рдХрддреЗ рд╣реИрдВ
template<class CompatibleTypes, class ReturnType> ReturnType sum(std::vector<boost::any>& args) { TypesDispatcher<CompatibleTypes, ReturnType> dispatcher; std::vector<boost::any>::size_type i; ReturnType result = ReturnType(); for(i=0; i < args.size(); i++) { Converter<ReturnType>* converter = dispatcher.getConverter(args[i]); if(converter) result += converter->cast(args[i]); } return result; } int main(int argc, char* argv[]) { typedef boost::mpl::vector<int,long, float, double> types; std::vector<boost::any> seq; seq.push_back(boost::any( 1 )); seq.push_back(boost::any( 2L )); seq.push_back(boost::any( 3.0F )); seq.push_back(boost::any( 4.0 )); double result = sum<types, double>(seq); }
рдкреВрд░рд╛ рдХреЛрдб рдЙрджрд╛рд╣рд░рдг
рдпрд╣рд╛рдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛
рд╣реИ ред
рдирддреАрдЬрддрди, рд╣рдореЗрдВ рдордирдорд╛рдиреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рд╛, рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рд▓рдЪреАрд▓реЗрдкрди рдиреЗ рдЙрдирдХреЗ рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ред