I've been reading about variadic templates, but having a hard time wrapping my mind around them.
The following code is from:
c++ - Call function with parameters extracted from string - Stack Overflow
Is it possible to do something like this with a string array, string vector, stringstream, or something to that effect instead of with an istream? istreams don't fit my usage. id like to pass in a string and split argument by spaces.
Can anyone point me in the right direction?
Code:#include <map> #include <string> #include <iostream> #include <sstream> #include <functional> #include <stdexcept> #include <type_traits> template<class F> struct stream_function; template<class R, class... Args> struct stream_function<R(Args...)>{ typedef R func_type(Args...); typedef std::function<func_type> function; static unsigned const arity = sizeof...(Args); template<class F> stream_function(F const& f) : _f(f) {} void operator()(std::istream& args, std::string* out_opt) const{ call(args, out_opt, typename std::is_void<R>::type()); } private: template<class T> static T get(std::istream& args){ T t; // must be default constructible if(!(args >> t)){ args.clear(); throw std::invalid_argument("invalid argument to stream_function"); } return t; } void call(std::istream& args, std::string*, std::true_type) const{ // void return _f(get<Args>(args)...); } void call(std::istream& args, std::string* out_opt, std::false_type) const{ // non-void return if(!out_opt) // no return wanted, redirect return call(args, 0, std::true_type()); R ret(_f(get<Args>(args)...)); std::stringstream conv; if(!(conv << ret)) throw std::runtime_error("bad return in stream_function"); *out_opt = conv.str(); } function _f; }; typedef std::function<void(std::istream&, std::string*)> func_type; typedef std::map<std::string, func_type> dict_type; void print(){ std::cout << "print()\n"; } int add(int a, int b){ return a + b; } int main(){ dict_type func_dict; func_dict["print"] = stream_function<void()>(print); func_dict["add"] = stream_function<int(int,int)>(add); for(;;){ std::cout << "Which function should be called?\n"; std::string tmp; std::cin >> tmp; auto it = func_dict.find(tmp); if(it == func_dict.end()){ std::cout << "Invalid function '" << tmp << "'\n"; continue; } tmp.clear(); try{ it->second(std::cin, &tmp); }catch(std::exception const& e){ std::cout << "Error: '" << e.what() << "'\n"; std::cin.ignore(); continue; } std::cout << "Result: " << (tmp.empty()? "none" : tmp) << '\n'; } }



LinkBack URL
About LinkBacks


