c++ - How to eliminate cast for constructor selection -


i've been playing around generic mechanism converting value 1 set of values another, based on boost's map_list_of template. 2 sets disjoint, it's not conversion 1 enumerated type another.

anyway, following code compiles , runs intended, i'm stuck on something. definition of enumtostring, right before main(), requires static_cast<const std::map<color, std::string> &> cast. (fwiw, constructor causes convert() function return key value string if cannot find key in map.) how can code compile without cast, while sticking c++03?

it might without cast there not enough type information available compiler figure out keytovalue constructor call.

#include <sstream> #include <map> #include "boost/assign.hpp"  template<typename k, typename v> // forward reference. class keytovalue;  template<typename k, typename v> // k v (value or callback default). v convert(const keytovalue<k, v> &t, const k &k) {     typename std::map<k, v>::const_iterator = t.m.find(k);     return == t.m.end() ? (t.mc == null ? t.d : t.mc(k)) : it->second; } template<typename k> // k string (auto default). (use sfinae ostream&operator<<(k).) std::string convert(const keytovalue<k, std::string> &t, const k &k) {     std::string v;     typename std::map<k, std::string>::const_iterator = t.m.find(k);     if (it == t.m.end())         if (t.auto_default)         {             std::ostringstream oss;             oss << k;             v = oss.str();         }         else v = t.mc == null ? t.d : t.mc(k);     else v = it->second;     return v; } template<typename k, typename v> // construct conversion object convert(). class keytovalue { public:     keytovalue(const std::map<k, std::string> &m) : // string w/auto default.         m(m), d(v()), mc(null), auto_default(true) { }     keytovalue(const std::map<k, v> &m, const v &d) : // v w/value default.         m(m), d(d), mc(null), auto_default(false) { }     keytovalue(const std::map<k, v> &m, v (*mc)(const k &)) : // callback.         m(m), d(v()), mc(mc), auto_default(false) { } private:     const std::map<k, v> m;     const v d; // default value.     v (*mc)(const k &); // callback returns default.     const bool auto_default; // automatically create default key?     template<typename k1, typename v1>         friend v1 convert(const keytovalue<k1, v1> &t, const k1 &k);     template<typename k1>         friend std::string convert(const keytovalue<k1, std::string> &t, const k1 &k); };  #include <iostream>  enum color { red, blue, orange, yellow, gold };  unsigned defaultunsigned(const color &myenum) {     return -1; }  const keytovalue<color, unsigned> enumtounsigned(boost::assign::map_list_of     (orange, 13) (yellow, 58), defaultunsigned ); const keytovalue<color, std::string> enumtostring(     static_cast<const std::map<color, std::string> &>(boost::assign::map_list_of     (orange, "orange") (yellow, "yellow") ) );  int main() {     std::cout << convert(enumtounsigned, yellow) << std::endl;     std::cout << convert(enumtounsigned, gold) << std::endl;     std::cout << convert(enumtostring, yellow) << std::endl;     std::cout << convert(enumtostring, gold) << std::endl; } 

this correct console output with cast:

58 4294967295 yellow 4 

without cast, g++ (-std=c++98) generates these diagnostics:

prog.cc:64:43: error: call of overloaded 'keytovalue(boost::assign_detail::generic_list<std::pair<color, const char*> >&)' ambiguous      (orange, "orange") (yellow, "yellow") );                                            ^ prog.cc:34:5: note: candidate: keytovalue<k, v>::keytovalue(const std::map<k, std::__cxx11::basic_string<char> >&) [with k = color; v = std::__cxx11::basic_string<char>]      keytovalue(const std::map<k, std::string> &m) : // string w/auto default.      ^ prog.cc:31:7: note: candidate: keytovalue<color, std::__cxx11::basic_string<char> >::keytovalue(const keytovalue<color, std::__cxx11::basic_string<char> >&)  class keytovalue        ^ 

update: here simplified version. how can rid of cast?

#include <map> #include "boost/assign.hpp"  struct keytovalue {     keytovalue(const std::map<int, bool> &m) { } } inttobool(     static_cast<const std::map<int, bool> &>(     boost::assign::map_list_of (3, true)));  int main() { } 

if understand design correctly, keytovalue helper class doesn't need copied. ambiguity due copy ctor, need eliminate that. in c++11, you'd =delete it. in c++03, make explicit instead.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -