Is there an elegant way to represent a map containing different types in C++? -
i'm building class want configure using various parameters may 1 of: int
, double
, string
(or const char *
matter). in language ruby, build initialization function takes hash keyed string. example:
class example def init_with_params params puts params end end e = example.new e.init_with_params({ "outputfile" => "/tmp/out.txt", "capturefps" => 25.0, "retrydelayseconds" => 5 })
how can create similar behavior in c++?
looking around found several posts talking boost::variant
. rather avoid using boost if limiting different types 3 types mentioned above rather clean solution can made.
edit: agree using designed , tested code such boost.variant better re-implementing same idea. in case, problem reduced using 3 basic types, looking simplest possible way of implementing it.
here cut down version of regularly use store program configuration properties, maybe find useful:
#include <map> #include <string> #include <sstream> #include <fstream> #include <iostream> #include <initializer_list> class config { // stored internally std::strings // read configuration file typedef std::map<std::string, std::string> prop_map; typedef prop_map::const_iterator prop_map_citer; prop_map props; public: // example constructor. have method read // values in file config(std::initializer_list<std::pair<std::string, std::string>> list) { for(const auto& p: list) props[p.first] = p.second; } // values converted requested whatever types // need be. default may given in case value // missing configuration file template<typename t> t get(const std::string& s, const t& dflt = t()) const { prop_map_citer found = props.find(s); if(found == props.end()) return dflt; t t; std::istringstream(found->second) >> std::boolalpha >> t; return t; } // std::strings need special handling (no conversion) std::string get(const std::string& s, const std::string& dflt = "") const { prop_map_citer found = props.find(s); return found != props.end() ? found->second : dflt; } }; int main() { const config cfg = { {"outputfile", "/tmp/out.txt"} , {"capturefps", "25.0"} , {"retrydelayseconds", "5"} }; std::string s; float f; int i; s = cfg.get("outputfile"); f = cfg.get<float>("capturefps"); = cfg.get<int>("retrydelayseconds"); std::cout << "s: " << s << '\n'; std::cout << "f: " << f << '\n'; std::cout << "i: " << << '\n'; }
Comments
Post a Comment