C++ Map Question

I have a template like this...

template <class EnumType, int size>
class Switch
{
   Switch() {}
   //......
   //Whatever the other code
}


I have several enums to instantiate the above...


Then I want to create  a Map like this...

std::map<std::string, Switch> switches;

When compiled, I am getting an error:

error: expected a type , got 'Switch'.

Why is that is not allowing me to create a Map of Switch?
prainAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
sarabandeConnect With a Mentor Commented:
to implement the factory pattern you have to derive from baseclass and store baseclass pointers. you then could create new objects of a derived class by using a virtual create function:

class Base
{
     static std::map<std::string, Base*> factoryMap;
public:
     static bool addToFactory(const std::string & k, Base* p) { factoryMap[k] = p; return true; }
     virtual Base* create() = 0;
};

template <class E, int i>
class X : public Base
{
... 
    virtual Base* create() { return new X<E, i>(); }
};

Open in new window


Sara
0
 
phoffricCommented:
std::map<std::string, Switch<...> > switches;
Should you be filling in the blanks(...)?
0
 
OrcbighterCommented:
Regardless of the solutions presented to you here, I think it is a serious programming error to create a class based on such a key word in C++.
It is a keyword used in the switch statement, and can be misleading. It makes it seem like you are trying to overload the switch statement.
Not good programming. You should choose another name for your class.
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
phoffricCommented:
"Switch" and "switches" are not keywords in C++ circa 2003. Are they keywords in C++11 ?
0
 
phoffricConnect With a Mentor Commented:
Here is an example of how to use a user defined template taken from:
http://www.cplusplus.com/doc/tutorial/templates/
template <class T>
class mypair {
    T values [2];
  public:
    mypair (T first, T second)
    {
      values[0]=first; values[1]=second;
    }
};

Open in new window

Two usage examples:
mypair<int> myobject (115, 36);
mypair<double> myfloats (3.0, 2.18);

Open in new window

Notice in this example that mypair always has <...> with the blanks filled in. mypair by itself is not a class type, but the example shows two different class types, namely, mypair<int> and mypair<double>.
0
 
phoffricCommented:
>> error: expected a type , got 'Switch'.
>> Why is that is not allowing me to create a Map of Switch?

Just as mypair is not a type, likewise, Switch is also not a type.
You need to create a type by adding <> and filling in the blanks with your two defined template parameters: class EnumType and int size.
0
 
sarabandeConnect With a Mentor Commented:
to add to above answers:

a template class allows you to have one implementation for many different types. but the template class cannot be used as a kind of 'baseclass' or 'metaclass' for all its instantiated classes.

if your goal is a container that handles textstrings associated to enum constants you might consider the following:

class SwitchMap
{
   std::map<std::pair<std::string, int>, std::string> switches;
public:
   void addEnum(const std::string & etype, int num, const char * ptextarr[])
   {
          for (int i = 0; i < num; ++i)
              switches[std::pair<std::string, int>(etype, i)] = ptextarr[i];
   }
  std::string getEnumText(const std::string & etype, int idx)
  {  
      std::map<std::pair<std::string, int>, std::string>::iterator f;  
      if ((f = switches.find(std::pair<std::string, int>(etype, idx))) != switches.end())
           return f->second;
      return "";
  }
};

Open in new window


you would use the above container like

SwitchMap enumSwitches;
...
enum E1
{
    a,
    b,
    c,
    e1_max
};

const char * E1_arr[e1_max] = { "a", "b", "c" };

enumSwitches.addEnum("E1", e1_max, E1_arr);

Open in new window

note, if you don't want to name the enum types by string you could use a further enum type which enumerates all enum types and serves as key part instead of the string.

Sara
0
 
prainAuthor Commented:
Guys,
Thanks for all these inputs. I think there are several great ideas here. But my target is to create a C++ Map container instantiated To a Anoter Class Template - called Switch (Created by out team).This particular class templates can be instantiated to different enum types and the size of enum element per enum so that the size can be used inside the Switch tamplate for processing. Here is the so called Switch template (just the skeleton).

template <class EnumType, int size>
class Switch
{
   Switch() {}
   //......
   //Whatever the other code
}

Now what I need is to create a Map container with Objects of the above Switch template where EACH INSTANCE OF Switch is instantiated for different enum types.

Unfortunately I cannot do much of a change in the design as the above Swith template is already used Like A Cancer in our system. So I have to use it without any changes that can harm the design.

In fact since I have not gotten a good answer to fit my need, I decided to go with a void *. I have tested few cases and they appear to work well.

Here is what I did....

/**Create a Map Container **/
typedef std::multimap<std::string, void* > SwitchMap;
typedef std::multimap<std::string, void* >::value_type SwitchPair;
typedef std::multimap<std::string, void* >::iterator SwitchPtr;

SwitchMap switches;

/** Create an object of Switch **/
Switch<SwitchTypes::OnOffSwitches, enumsize>* test = new Switch<SwitchTypes::OnOffSwitches, enumsize>();

/**Now add to the Map contaner **/
switches.insert(SwitchPair("Some Name", test));

Then I can find any of the objects by name...
SwitchPtr thePtr = switches.find("Some Name");

So the above works well....
0
 
sarabandeCommented:
i wonder what you would do with the void pointer when retrieved from map. you only could get any benefit from it if you cast it to the right type again. in my opinion such a void pointer is of no value.

you could try to derive the template class from a baseclass and then use the baseclass pointer for the map. when retrieving the baseclass pointer you could use virtual functions to step into the template class. even then i would like to know what you would do with the class as in my opinion you have to insert more information into the container than you can get from it.

Sara
0
 
prainAuthor Commented:
Yes. I will use the void pointer to cast to different Switch objects returned from the Map via getters. I use this Map somewhat like a factory.
0
 
prainAuthor Commented:
Yep!. Thanks.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.