f



Need template magic (or how I learned to love template-function-scope static vars)

I've been trying to come up with a way of mapping enums to strings
that's usable for programmers that don't want to deal with templates.
My enums are numbered 0,1,2,... so I'm not worried about duplicate
keys.

My previous approaches always looked something like this:

enum foo { zero, one, two };
mapper<foo> fooMapper;

where the fooMapper would either set up the map in the constructor
by calling something like Add(zero, "zero") or the user would be
required to set up a static member array that contained the mappings.

The code was fairly simple but I was wondering whether it was possible
to build something without <> syntax. (At this point it's a fairly
academic
exercise.)

Anyway, this is what I came up with. Please critique and suggest
improvements. What I don't like is that the static var just sits there
trapped at function scope. There's no way to extend the functionality
other than packing more options into the Mapper function via
arguments such as "setString".

Thanks,
Andrew Queisser

=========================

#include <iostream>
#include <string>
#include <map>
using namespace std;

template <class T> bool SetString(T key, string &s)
{
 return Mapper(key, s, true);
}

template <class T> bool GetString(T key, string &s)
{
 return Mapper(key, s, false);
}

template <class T> bool Mapper(T key, string &s, bool setString)
{
 // function-scope static variable acts as Singleton
 static map<T, string> s_ksMap;

 bool found = true;

 if (setString)
  s_ksMap[key] = s;
 else
 {
  map<T,string>::iterator sPos = s_ksMap.find(key);
  if (sPos == s_ksMap.end())
   found = false;
  else
   s = sPos->second;
 }

 return found;
}


// two enums with the same values
enum test1 { zero, one, two, three };
enum test2 { null, eins, zwei, drei };

void main(void)
{
 string s1 = "one";
 string s2 = "eins";
 test1 t1 = one;
 test2 t2 = eins;
 SetString(t1, s1);
 SetString(t2, s2);
 string s3;
 string s4;
 GetString(t1, s3);
 GetString(t2, s4);

 // output should be "s3=one,s4=eins"
 cout << "s3=" << s3 << ",s4=" << s4 << endl;
}

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
andrew_queisser
6/27/2003 8:55:32 PM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

1 Replies
555 Views

Similar Articles

[PageSpeed] 51

"andrew queisser" <andrew_queisser@hp.com> wrote in message
news:ad2f1094.0306270744.3811b8a3@posting.google.com...
> I've been trying to come up with a way of mapping enums to strings
> that's usable for programmers that don't want to deal with templates.
> My enums are numbered 0,1,2,... so I'm not worried about duplicate
> keys.
>
> My previous approaches always looked something like this:
>
> enum foo { zero, one, two };
> mapper<foo> fooMapper;
>
> where the fooMapper would either set up the map in the constructor
> by calling something like Add(zero, "zero") or the user would be
> required to set up a static member array that contained the mappings.
>
> The code was fairly simple but I was wondering whether it was possible
> to build something without <> syntax. (At this point it's a fairly
> academic
> exercise.)
>
> Anyway, this is what I came up with. Please critique and suggest
> improvements. What I don't like is that the static var just sits there
> trapped at function scope. There's no way to extend the functionality
> other than packing more options into the Mapper function via
> arguments such as "setString".
>
> Thanks,
> Andrew Queisser
>
> =========================
>
> #include <iostream>
> #include <string>
> #include <map>
> using namespace std;
>
> template <class T> bool SetString(T key, string &s)
> {
>  return Mapper(key, s, true);
> }
>
> template <class T> bool GetString(T key, string &s)
> {
>  return Mapper(key, s, false);
> }
>
> template <class T> bool Mapper(T key, string &s, bool setString)
> {
>  // function-scope static variable acts as Singleton
>  static map<T, string> s_ksMap;
>
>  bool found = true;
>
>  if (setString)
>   s_ksMap[key] = s;
>  else
>  {
>   map<T,string>::iterator sPos = s_ksMap.find(key);
>   if (sPos == s_ksMap.end())
>    found = false;
>   else
>    s = sPos->second;
>  }
>
>  return found;
> }
>
>
> // two enums with the same values
> enum test1 { zero, one, two, three };
> enum test2 { null, eins, zwei, drei };
>
> void main(void)
> {
>  string s1 = "one";
>  string s2 = "eins";
>  test1 t1 = one;
>  test2 t2 = eins;
>  SetString(t1, s1);
>  SetString(t2, s2);
>  string s3;
>  string s4;
>  GetString(t1, s3);
>  GetString(t2, s4);
>
>  // output should be "s3=one,s4=eins"
>  cout << "s3=" << s3 << ",s4=" << s4 << endl;
> }

I think you are shooting with cannon balls and creating a maintainance
nightmare.
How about simply this:

enum EFieldFormat
{
   EFieldFormatNone,
   EFieldFormatDefault,
   EFieldFormatSystem,
   EFieldFormatUser,
   EFieldFormatAssert
};

std::string _getString(EFieldFormat _frmt)
{
   switch (_frmt)
   {
      case EFieldFormatNone: return "EFieldFormatNone"; break;
      case EFieldFormatDefault: return "EFieldFormatDefault"; break;
      case EFieldFormatSystem: return "EFieldFormatSystem"; break;
      case EFieldFormatUser: return "EFieldFormatUser"; break;
      default: assert(false); return "!!!"; break;
   }
}

enum EColumnId
{
   EColumnId1,
   EColumnId2,
   EColumnId3,
   EColumnId4,
   EColumnId5
};

std::string _getString(EColumnId _id)
{
   switch (_id)
   {
      case EColumnId1: return "I"; break;
      case EColumnId2: return "II"; break;
      case EColumnId3: return "III"; break;
      case EColumnId4: return "IV"; break;
      case EColumnId5: return "V"; break;
      default: assert(false); return "!!!"; break;
   }
}

-----

    std::cout << _getString(EFieldFormatSystem) << std::endl;
    std::cout << _getString(EFieldFormatAssert) << std::endl;
    std::cout << _getString(EColumnId4) << std::endl;

-----

(I allways prepend the enum type name in the enum items because enums kind
of suck)

Conrad Weyns.


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
Conrad
6/28/2003 11:20:21 PM
Reply: