Solved

C++ Map Question

Posted on 2013-05-10
11
306 Views
Last Modified: 2014-03-26
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?
0
Comment
Question by:prain
  • 4
  • 3
  • 3
  • +1
11 Comments
 
LVL 32

Expert Comment

by:phoffric
ID: 39156720
std::map<std::string, Switch<...> > switches;
Should you be filling in the blanks(...)?
0
 
LVL 9

Expert Comment

by:Orcbighter
ID: 39158899
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
 
LVL 32

Expert Comment

by:phoffric
ID: 39159009
"Switch" and "switches" are not keywords in C++ circa 2003. Are they keywords in C++11 ?
0
 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 67 total points
ID: 39159020
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
 
LVL 32

Expert Comment

by:phoffric
ID: 39159026
>> 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 33

Assisted Solution

by:sarabande
sarabande earned 133 total points
ID: 39163749
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
 

Author Comment

by:prain
ID: 39164561
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
 
LVL 33

Expert Comment

by:sarabande
ID: 39165435
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
 

Author Comment

by:prain
ID: 39165458
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
 
LVL 33

Accepted Solution

by:
sarabande earned 133 total points
ID: 39167193
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
 

Author Comment

by:prain
ID: 39167876
Yep!. Thanks.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
zeroMAx challenge 20 88
sumDigits  challenge 7 75
word0 challenge 3 79
delphi parse string to params 3 101
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now