2

Goal: a template for a std map w string keys + optional true/false param for case sensitivity

Got it to work as follows, but the result is ugly - there must be a better way !

//step 1: templated typdefs for case-insensitive (ci), case-sensitive (cs) maps
template <typename T> struct ci_map { typedef std::map<std::string, T, ci_compare_string> type; }; //ci version
template <typename T> struct cs_map { typedef std::map<std::string, T                   > type; }; //cs version

//step 2: a template specialized to select on the of the two versions
template<typename T, bool ci> struct map_choice           {                                }; //empty decl
template<typename T>          struct map_choice<T, true>  { typedef ci_map<T> map_version; }; //specialize ci = true
template<typename T>          struct map_choice<T, false> { typedef cs_map<T> map_version; }; //specialize ci = false

//final step, but VS 2008 compile error: 'map_choice<T,ci>::map_version::type': dependent name is not a type
template<typename T, bool ci=true> 
struct mymap { typedef map_choice<T, ci>::map_version::type type; };
//too bad ... usage would have been concise ==>  "mymap<int>::type  mymap_instance;"

//final step: works, but ugly
template<typename T, bool ci=true> 
struct mymap { typedef map_choice<T, ci> type; };
//usage (ugly !!!)
mymap<int>::type::map_version::type    mymap_instance;  //ouch

Any suggestions for improvement ?

tpascale
  • 2,516
  • 5
  • 25
  • 38

2 Answers2

2
template<typename T, bool ci=true> 
struct mymap { typedef typename map_choice<T, ci>::map_version::type type; };

Will work fine. Read: Where and why do I have to put the "template" and "typename" keywords?

Community
  • 1
  • 1
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Not only it will work fine, it is required by the standard that the `typename` be put there. It's not just MSVC complaining for no reason. – John Zwinck Feb 21 '13 at 13:08
  • @JohnZwinck I know this. That's why i give link. – ForEveR Feb 21 '13 at 13:08
  • 1
    I wrote my comment as you were adding the link. :) I just wanted to make sure the OP didn't think it was MSVC's fault, as the comment in his code seemed to suggest it might be. – John Zwinck Feb 21 '13 at 13:11
  • ignore prev comment - works just fine - typo on my 1st attempt caused me to think there was a problem. – tpascale Feb 21 '13 at 13:42
2

How about this:

template <bool ci>
struct Comparator
{
  typedef ci_compare_string type;
};

template<>
struct Comparator<false>
{
  typedef std::less<std::string> type;
};


template <typename T, bool ci = true>
struct mymap
{
  typedef std::map<std::string, T, typename Comparator<ci>::type> type;
};
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455