C++ How to dispatch to different template function by tag -
there's lots of template functions called f1,f2,f3…
how dispatch runtime-known int different template functions?
of course can use switch that, every time add more template functions or delete template functions, have modify switch again , again. how can in more elegant way?
templates not real-exsited functions can't make std::map of functions pointers.
template<typename t> std::optional<t> f1(){...} template<typename t> std::optional<t> f2(){...} template<typename t> std::optional<t> f3(){...} template<typename t> std::optional<t> f4(){...} template<typename t> auto dispatch(int tag){ switch(i){ case 1: return f1<t>(); case 2: return f2<t>(); case 3: return f3<t>(); case 4: return f4<t>(); }// have modify these if add or delete template functions }
here explanation command pattern, guess looking for.
there no templated functions, rewrote it. not doing purpose (convert numbers) can choose function want call , templated.
#include <iostream> #include <string> #include <bitset> #include <sstream> #include <map> #include <cctype> template <typename t> class converter { public: virtual std::string convert(t) = 0; virtual ~converter() {} }; template <typename t> class hex_converter : public converter<t> { public: std::string convert(t i) { return "h: " + i; } }; template <typename t> class oct_converter : public converter<t> { public: std::string convert(t i) { return "o: " + i; } }; template <typename t> class bin_converter : public converter<t> { public: std::string convert(t i) { return "b: " + i; } }; class dictionary { std::map<char, converter<std::string>*> dict; public: dictionary() { dict.insert( std::make_pair( 'b', new bin_converter<std::string> ) ); dict.insert( std::make_pair( 'o', new oct_converter<std::string> ) ); dict.insert( std::make_pair( 'h', new hex_converter<std::string> ) ); } converter<std::string>* lookup(char x) { std::map<char, converter<std::string>*>::const_iterator iter; iter = dict.find( toupper(x) ); if( iter != dict.end() ) return iter->second; else return null; } ~dictionary() { while( dict.begin() != dict.end() ) { delete dict.begin()->second; dict.erase( dict.begin() ); } } }; int main() { using namespace std; char ch = 'h'; string output = ""; dictionary dict; converter<std::string>* con = dict.lookup( ch ); if( con != null ) output = con->convert( "test" ); else output = "invalid"; cout << "result: " << output; }
Comments
Post a Comment