?
Solved

C++ Map Question

Posted on 2013-05-10
11
Medium Priority
?
337 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 
LVL 32

Assisted Solution

by:phoffric
phoffric earned 201 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
 
LVL 35

Assisted Solution

by:sarabande
sarabande earned 399 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 35

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 35

Accepted Solution

by:
sarabande earned 399 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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Having just graduated from college and entered the workforce, I don’t find myself always using the tools and programs I grew accustomed to over the past four years. However, there is one program I continually find myself reverting back to…R.   So …
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
Suggested Courses

762 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