Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Initialising a map

Reply
Thread Tools

Initialising a map

 
 
Angus
Guest
Posts: n/a
 
      06-27-2008
Should I be able to do something like this:

static const std::map<RequestType, string> RequestMap = {
{ AOpenEx, "AOpenEx" },
{ AClose, "AClose" },
{ ARegister, "ARegister" },
{ AUnregister, "Unregister" } };

RequestType is an enum.

I can't compile it. Or can I not initialise with an array like this?
 
Reply With Quote
 
 
 
 
David Côme
Guest
Posts: n/a
 
      06-27-2008
On Fri, 27 Jun 2008 15:06:09 +0200, Angus <(E-Mail Removed)> wrote:

> Should I be able to do something like this:
>
> static const std::map<RequestType, string> RequestMap = {
> { AOpenEx, "AOpenEx" },
> { AClose, "AClose" },
> { ARegister, "ARegister" },
> { AUnregister, "Unregister" } };
>
> RequestType is an enum.
>
> I can't compile it. Or can I not initialise with an array like this?



look at boost::assign and particularly at map_list_of
 
Reply With Quote
 
 
 
 
Angus
Guest
Posts: n/a
 
      06-27-2008
On 27 Jun, 14:13, David Cme <(E-Mail Removed)> wrote:
> On Fri, 27 Jun 2008 15:06:09 +0200, Angus <(E-Mail Removed)> wrote:
> > Should I be able to do something like this:

>
> > * static const std::map<RequestType, string> RequestMap = {
> > * * { AOpenEx, * * * * * * * * * *"AOpenEx" },
> > * * { AClose, * * * * * * * * * * "AClose" },
> > * * { ARegister, * * * * * * * * "ARegister" },
> > * * { AUnregister, * * * * * * * "Unregister" } };

>
> > RequestType is an enum.

>
> > I can't compile it. *Or can I not initialise with an array like this?

>
> look at boost::assign and particularly at map_list_of


Unfortunately I cannot use boost here. Maybe it is easier not to use
a map as the data is fairly static. What is the easiest way for me to
create a mapping like this?
 
Reply With Quote
 
rep_movsd
Guest
Posts: n/a
 
      06-27-2008
On Jun 27, 4:30*pm, Angus <(E-Mail Removed)> wrote:
> On 27 Jun, 14:13, David Cme <(E-Mail Removed)> wrote:
>
> > On Fri, 27 Jun 2008 15:06:09 +0200, Angus <(E-Mail Removed)> wrote:
> > > Should I be able to do something like this:

>
> > > * static const std::map<RequestType, string> RequestMap = {
> > > * * { AOpenEx, * * * * * * * * * *"AOpenEx" },
> > > * * { AClose, * * * * * * * * * * "AClose" },
> > > * * { ARegister, * * * * * * * * "ARegister" },
> > > * * { AUnregister, * * * * * * * "Unregister" } };

>
> > > RequestType is an enum.

>
> > > I can't compile it. *Or can I not initialise with an array like this?

>
> > look at boost::assign and particularly at map_list_of

>
> Unfortunately I cannot use boost here. *Maybe it is easier not to use
> a map as the data is fairly static. *What is the easiest way for me to
> create a mapping like this?


Maybe use a loop?

RequestType keys[] = {AOpenEx, AClose, ARegister, AUnregister,};
const char* vals[] = {"AOpenEx", "AClose", "ARegister",
"AUnregister"};

std::map<RequestType, string> myMap;
for(int n = 0; n < (sizeof(keys) / sizeof(keys[0])); ++n)
{
myMap[keys[n]] = vals[n];
}

....

If you are always going to have the string exactly the same as
RequestType enum and you have a large number of such, maybe you can do
some preprocessor stuff, this will avoid any errors while typing.

Vivek


 
Reply With Quote
 
SeanW
Guest
Posts: n/a
 
      06-27-2008
On Jun 27, 9:30 am, Angus <(E-Mail Removed)> wrote:
> On 27 Jun, 14:13, David Cme <(E-Mail Removed)> wrote:
>
> > On Fri, 27 Jun 2008 15:06:09 +0200, Angus <(E-Mail Removed)> wrote:
> > > Should I be able to do something like this:

>
> > > static const std::map<RequestType, string> RequestMap = {
> > > { AOpenEx, "AOpenEx" },
> > > { AClose, "AClose" },
> > > { ARegister, "ARegister" },
> > > { AUnregister, "Unregister" } };

>
> > > RequestType is an enum.

>
> > > I can't compile it. Or can I not initialise with an array like this?

>
> > look at boost::assign and particularly at map_list_of

>
> Unfortunately I cannot use boost here. Maybe it is easier not to use
> a map as the data is fairly static. What is the easiest way for me to
> create a mapping like this?


How about:

typedef std::map<RequestType, string> RequestMap;
RequestMap tmp_map;
tmp_map[AOpenEx] = "AOpenEx";
tmp_map[AClose] = "AClose";
tmp_map[ARegister] = "ARegister";
tmp_map[AUnregister] = "AUnregister";
static const RequestMap const_map(tmp_map);

A bit ugly, but it works.

You might also be interested in this proposal for future
C++ initializer lists:

http://anubis.dkuug.dk/jtc1/sc22/wg2...2003/n1509.pdf


Sean
 
Reply With Quote
 
AnonMail2005@gmail.com
Guest
Posts: n/a
 
      06-27-2008
On Jun 27, 9:06*am, Angus <(E-Mail Removed)> wrote:
> Should I be able to do something like this:
>
> * static const std::map<RequestType, string> RequestMap = {
> * * { AOpenEx, * * * * * * * * * *"AOpenEx" },
> * * { AClose, * * * * * * * * * * "AClose" },
> * * { ARegister, * * * * * * * * "ARegister" },
> * * { AUnregister, * * * * * * * "Unregister" } };
>
> RequestType is an enum.
>
> I can't compile it. *Or can I not initialise with an array like this?

If your map contents won't change much in the future, just initialize
it
from two arrays or an array of POD structs.

If the map will be added to in the future, you may want to look into
having a register function. See Modern C++ Design for how to do this.
In that book, he used this technique to register names/creation
function pointers with a factory.

HTH
 
Reply With Quote
 
tragomaskhalos
Guest
Posts: n/a
 
      06-27-2008
On Jun 27, 2:06*pm, Angus <(E-Mail Removed)> wrote:
> Should I be able to do something like this:
>
> * static const std::map<RequestType, string> RequestMap = {
> * * { AOpenEx, * * * * * * * * * *"AOpenEx" },
> * * { AClose, * * * * * * * * * * "AClose" },
> * * { ARegister, * * * * * * * * "ARegister" },
> * * { AUnregister, * * * * * * * "Unregister" } };
>
> RequestType is an enum.


Check this out (a previous thread on the same question):
http://groups.google.com/group/comp....a984af51eba51a

 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      06-27-2008
Angus wrote:
> static const std::map<RequestType, string> RequestMap = {
> { AOpenEx, "AOpenEx" },
> { AClose, "AClose" },
> { ARegister, "ARegister" },
> { AUnregister, "Unregister" } };


Followup question: Will this be possible with the upcoming C++
standard? (AFAIK something similar will be possible with std::vector.)
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      06-27-2008
On Jun 27, 3:06 pm, Angus <(E-Mail Removed)> wrote:
> Should I be able to do something like this:


> static const std::map<RequestType, string> RequestMap = {
> { AOpenEx, "AOpenEx" },
> { AClose, "AClose" },
> { ARegister, "ARegister" },
> { AUnregister, "Unregister" } };


> RequestType is an enum.


> I can't compile it. Or can I not initialise with an array
> like this?


You can initialize it with an array. You can't use agglomerate
initialization on it, however, because it isn't an agglomerate.

The general solution is to declare something like:

typedef std::map< RequestType, string >
RequestMap ;

struct RequestMapInitializer
{
RequestType key ;
char const* value ;
operator RequestMap::value_type() const
{
return RequestMap::value_type(
key, std::string( value ) ;
}
}
RequestMapInitializer const initializer[] =
{
{ AOpenEx , "AOpenEx" },
{ AClose , "AClose" },
{ ARegister , "ARegister" },
{ AUnregister, "Unregister" },
}

RequestMap requestMap( begin( initializer ),
end( initializer ) ) ;

(with the usual definitions for begin and end, of course).

For small things like this, I find just using a C style array
and std::find simpler, and perfectly adequate. So I wrote a
template class StaticMap

template< typename MappedType,
typename KeyType = char const* >
struct StaticMap
{
KeyType key ;
MappedType value ;

class Matcher
{
public:
explicit Matcher( KeyType const& targetKey )
: myKey( targetKey )
{
}

bool operator()( StaticMap const& obj )
const
{
return myKey == obj.key ;
}

private:
KeyType myKey ;
} ;

static StaticMap const*
find(
StaticMap const* begin,
StaticMap const* end,
KeyType const& value )
{
return std::find_if( begin, end, Matcher( value ) ) ;
}
} ;

(Originally, the key type was always char const*, since that
corresponded to most of my uses. That's why it's unexpectedly
the second template argument.)

--
James Kanze (GABI Software) email:(E-Mail Removed)
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
 
Reply With Quote
 
jl_post@hotmail.com
Guest
Posts: n/a
 
      06-27-2008
On Jun 27, 7:06 am, Angus <(E-Mail Removed)> wrote:
> Should I be able to do something like this:
>
> static const std::map<RequestType, string> RequestMap = {
> { AOpenEx, "AOpenEx" },
> { AClose, "AClose" },
> { ARegister, "ARegister" },
> { AUnregister, "Unregister" } };
>
> RequestType is an enum.
>
> I can't compile it. Or can I not initialise with an array like this?



To be honest, I don't know of a simple way to do what you want
using both "const" and a non-pointer. But if you don't mind using a
const pointer, you can do it this way:


#include <iostream>
#include <map>
#include <string>

enum RequestType
{
AOpenEx,
AClose,
ARegister,
AUnregister
};

int main(int argc, char ** argv)
{
static const std::map<RequestType,std::string> * RequestMap = NULL;
if (!RequestMap)
{
static std::map<RequestType,std::string> tmpMap;
tmpMap[AOpenEx] = "AOpenEx";
tmpMap[AClose] = "AClose";
tmpMap[ARegister] = "ARegister";
tmpMap[AUnregister] = "AUnregister";

RequestMap = &tmpMap;
}

std::map<RequestType,std::string>::const_iterator it
= RequestMap->find(AOpenEx);
std::cout << "RequestMap[AOpenEx] = \""
<< it->second << '"'
<< std::endl;

// This next line shouldn't compile (due to "const"):
// (*RequestMap)[AOpenEx] = "blah";

return 0;
}


This approach requires you to use RequestMap as a pointer, which
might make your syntax a little messier.

But if you'd rather not use a pointer (and are fine with not using
"const"), you might prefer this next approach:


#include <iostream>
#include <map>
#include <string>

enum RequestType
{
AOpenEx,
AClose,
ARegister,
AUnregister
};

int main(int argc, char ** argv)
{
static std::map<RequestType,std::string> RequestMap;
if (RequestMap.empty())
{
RequestMap[AOpenEx] = "AOpenEx";
RequestMap[AClose] = "AClose";
RequestMap[ARegister] = "ARegister";
RequestMap[AUnregister] = "AUnregister";
}

std::cout << "RequestMap[AOpenEx] = \""
<< RequestMap[AOpenEx] << '"'
<< std::endl;

// Unfortunately, this next line DOES compile:
RequestMap[AOpenEx] = "blah";

return 0;
}


The syntax in the second approach is simpler, I think. However,
this approach suffers from the fact that RequestMap is not declared
"const", so it can be freely populated/modified, which is probably not
what you want.

However, both approaches benefit from the fact that RequestMap is
only populated once no matter how many times the function it is in is
called.

I hope this helps, Angus.

-- Jean-Luc
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Initialising map member without copy Paul Brettschneider C++ 23 03-05-2008 09:25 PM
Initialising UserControls Dave ASP .Net 2 09-03-2004 12:37 PM
Re: Dynamic user control loading/initialising Phil Winstanley [Microsoft MVP ASP.NET] ASP .Net 2 06-20-2004 01:26 PM
Dynamic user control loading/initialising Jo Inferis ASP .Net 0 06-20-2004 12:51 PM
Initialising a signal jan VHDL 3 12-23-2003 01:25 PM



Advertisments