Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > std::map associative container question

Reply
Thread Tools

std::map associative container question

 
 
aaragon
Guest
Posts: n/a
 
      09-21-2006
Hello everyone,

I would like to know if there is a way to use the std::map to store
different types for one of its two types. That is, I'm trying to use
it as:

typedef std::map<string,double> Map;

but instead of double, I have integers, even booleans so I guess that
the use of double waste a lot of storage. Is there any way to do this?
Maybe with a typename?

Thank you all,

a^2

 
Reply With Quote
 
 
 
 
Thomas Tutone
Guest
Posts: n/a
 
      09-21-2006
aaragon wrote:


> I would like to know if there is a way to use the std::map to store
> different types for one of its two types. That is, I'm trying to use
> it as:
>
> typedef std::map<string,double> Map;
>
> but instead of double, I have integers, even booleans so I guess that
> the use of double waste a lot of storage. Is there any way to do this?
> Maybe with a typename?


Take a look at boost::any. If that's no help, you may need to describe
a bit more what it is you are trying to do. By the way, although I can
see good reasons not to use doubles, why do you care about wasting
storage? Is the map really that big?

Best regards,

Tom

 
Reply With Quote
 
 
 
 
aaragon
Guest
Posts: n/a
 
      09-21-2006

Thomas Tutone wrote:
> aaragon wrote:
>
>
> > I would like to know if there is a way to use the std::map to store
> > different types for one of its two types. That is, I'm trying to use
> > it as:
> >
> > typedef std::map<string,double> Map;
> >
> > but instead of double, I have integers, even booleans so I guess that
> > the use of double waste a lot of storage. Is there any way to do this?
> > Maybe with a typename?

>
> Take a look at boost::any. If that's no help, you may need to describe
> a bit more what it is you are trying to do. By the way, although I can
> see good reasons not to use doubles, why do you care about wasting
> storage? Is the map really that big?
>
> Best regards,
>
> Tom


Well, it's not that the map is big, but also when you request the key,
then the value is returned. Therefore, sometimes I'm expecting a bool
but instead I'm receiving a double (and I don't want to convert the
values nor put a specifier in front as (bool) for example). I was
wondering that maybe there is a templetized way to do this. For
example,

template<typename T>
....
typedef std::map<string,T> Map;

but I don't think it may work.....

 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-21-2006
aaragon wrote:

> Hello everyone,
>
> I would like to know if there is a way to use the std::map to store
> different types for one of its two types. That is, I'm trying to use
> it as:
>
> typedef std::map<string,double> Map;
>
> but instead of double, I have integers, even booleans so I guess that
> the use of double waste a lot of storage. Is there any way to do this?


The short answer is: no. The long answer is: yes, but the overhead incurred
be the logic needed to arrange for one object to represent values from
possible different types is very likely going to null and void all possible
gains in storage consumption.

E.g., you could do something like:

struct number {
~number();
};

struct number_double : public base {
double value;
};

struct number_int : public base {
int value;
};

....

std::map<string,number*> Map;

Then you have the overhead of one pointer per object and a real hassle to
sort out which object has which type (using dynamic_cast or some such
thing). In order for that to work, number needs to be polymorphic, which
usually means you have a vtable pointer. Given that heap allocation occurs
in chunks determined by the algorithm for new, we might already look at 20
to 36 bytes per entry in the map.

Have you verified that you really cannot afford the memory overhead from
converting everything to double, or are you engaging in premature
optimization?


Best

Kai-Uwe Bux
 
Reply With Quote
 
Thomas Tutone
Guest
Posts: n/a
 
      09-21-2006
aaragon wrote:

> Thomas Tutone wrote:
> > aaragon wrote:
> >
> >
> > > I would like to know if there is a way to use the std::map to store
> > > different types for one of its two types. That is, I'm trying to use
> > > it as:
> > >
> > > typedef std::map<string,double> Map;
> > >
> > > but instead of double, I have integers, even booleans so I guess that
> > > the use of double waste a lot of storage. Is there any way to do this?
> > > Maybe with a typename?

> >
> > Take a look at boost::any. If that's no help, you may need to describe
> > a bit more what it is you are trying to do. By the way, although I can
> > see good reasons not to use doubles, why do you care about wasting
> > storage? Is the map really that big?
> >
> > Best regards,
> >
> > Tom

>
> Well, it's not that the map is big, but also when you request the key,
> then the value is returned. Therefore, sometimes I'm expecting a bool
> but instead I'm receiving a double (and I don't want to convert the
> values nor put a specifier in front as (bool) for example). I was
> wondering that maybe there is a templetized way to do this. For
> example,
>
> template<typename T>
> ...
> typedef std::map<string,T> Map;
>
> but I don't think it may work.....


No, that definitely won't work. C++ is a strongly typed language, and
you need to instantiate the map using a particular type. As I said,
look at boost::any (see www.boost.org). Or maybe you can just do
something like the following:

struct Aaragon_multi_type {
int i;
double d;
bool b;
};

std::map<std::string, Aaragon_multi_type map;

Not space efficient, but would let store value of any of those in the
map...

Again, if you don't tell us what it is you want to do - i.e., why do
you want to store different types? - it's awfully hard to provide
useful advice.

Best regards,

Tom

 
Reply With Quote
 
aaragon
Guest
Posts: n/a
 
      09-21-2006
Kai-Uwe Bux wrote:
> aaragon wrote:
>
> > Hello everyone,
> >
> > I would like to know if there is a way to use the std::map to store
> > different types for one of its two types. That is, I'm trying to use
> > it as:
> >
> > typedef std::map<string,double> Map;
> >
> > but instead of double, I have integers, even booleans so I guess that
> > the use of double waste a lot of storage. Is there any way to do this?

>
> The short answer is: no. The long answer is: yes, but the overhead incurred
> be the logic needed to arrange for one object to represent values from
> possible different types is very likely going to null and void all possible
> gains in storage consumption.
>
> E.g., you could do something like:
>
> struct number {
> ~number();
> };
>
> struct number_double : public base {
> double value;
> };
>
> struct number_int : public base {
> int value;
> };
>
> ...
>
> std::map<string,number*> Map;
>
> Then you have the overhead of one pointer per object and a real hassle to
> sort out which object has which type (using dynamic_cast or some such
> thing). In order for that to work, number needs to be polymorphic, which
> usually means you have a vtable pointer. Given that heap allocation occurs
> in chunks determined by the algorithm for new, we might already look at 20
> to 36 bytes per entry in the map.
>
> Have you verified that you really cannot afford the memory overhead from
> converting everything to double, or are you engaging in premature
> optimization?
>
>
> Best
>
> Kai-Uwe Bux


Yes, I'm trying to write the code as optimal as possible from the
beginning. It is not that I have a big map. I'm trying to build a
genetic algorithm library so I decided to store all the possible
variables of the problem in a map. These variables include from
population size (an unsigned int) to probabilities of crossover and
mutation (double variables), or even boolean types (to see if a random
seed was given). I thought it would be cool to have everything in an
associative container so when I type map[popSize] then I get the
population size of the problem. However, as you can see the types are
different. What I'm doing right now is
typedef std::map<string,double> Map;
so when I need an unsigned int for example, I put an identifier in
front (size_t)Map[popSize]. This works but I thought it was a better
way to do this.
I never thought that having a map for different types was as
complicated as this. Thank you guys for your help.

 
Reply With Quote
 
jois.de.vivre@gmail.com
Guest
Posts: n/a
 
      09-21-2006
Thomas Tutone wrote:
> aaragon wrote:
>
> > Thomas Tutone wrote:
> > > aaragon wrote:
> > >
> > >
> > > > I would like to know if there is a way to use the std::map to store
> > > > different types for one of its two types. That is, I'm trying to use
> > > > it as:
> > > >
> > > > typedef std::map<string,double> Map;
> > > >
> > > > but instead of double, I have integers, even booleans so I guess that
> > > > the use of double waste a lot of storage. Is there any way to do this?
> > > > Maybe with a typename?
> > >
> > > Take a look at boost::any. If that's no help, you may need to describe
> > > a bit more what it is you are trying to do. By the way, although I can
> > > see good reasons not to use doubles, why do you care about wasting
> > > storage? Is the map really that big?
> > >
> > > Best regards,
> > >
> > > Tom

> >
> > Well, it's not that the map is big, but also when you request the key,
> > then the value is returned. Therefore, sometimes I'm expecting a bool
> > but instead I'm receiving a double (and I don't want to convert the
> > values nor put a specifier in front as (bool) for example). I was
> > wondering that maybe there is a templetized way to do this. For
> > example,
> >
> > template<typename T>
> > ...
> > typedef std::map<string,T> Map;
> >
> > but I don't think it may work.....

>
> No, that definitely won't work. C++ is a strongly typed language, and
> you need to instantiate the map using a particular type. As I said,
> look at boost::any (see www.boost.org). Or maybe you can just do
> something like the following:
>
> struct Aaragon_multi_type {
> int i;
> double d;
> bool b;
> };
>
> std::map<std::string, Aaragon_multi_type map;
>
> Not space efficient, but would let store value of any of those in the
> map...
>


What if you used union instead of struct? That would be more space
efficient.

> Again, if you don't tell us what it is you want to do - i.e., why do
> you want to store different types? - it's awfully hard to provide
> useful advice.
>
> Best regards,
>
> Tom


 
Reply With Quote
 
Jens Theisen
Guest
Posts: n/a
 
      09-21-2006
"aaragon" <(E-Mail Removed)> writes:

> typedef std::map<string,double> Map;
> so when I need an unsigned int for example, I put an identifier in
> front (size_t)Map[popSize]. This works but I thought it was a better
> way to do this.


Is there a reason why you can't use different maps? I can think of
cases where you can't, or don't want to, but I suspect that you
actually should better do.

Frankly, I think that the language making it hard for you to follow
your approach is a sign that you're trying to do the wrong thing.

You want to store a variable popSize as a value of a map. Is there a
reason why you can't use a proper variable: size_t popSize? Do you
have an arbitrary number of those? How are they used?

If you could post some code of what you're really trying to do, this
would help a lot.

> I never thought that having a map for different types was as
> complicated as this.


It's simple with boost::any, and for double, int and bool alone a
union is also a possibility. However, this is most certainly not want
you want to do.

> Yes, I'm trying to write the code as optimal as possible from the
> beginning. It is not that I have a big map.


You know that early optimisation is the source of all evil, do you?
But that's a different matter.

Jens
 
Reply With Quote
 
aaragon
Guest
Posts: n/a
 
      09-21-2006

Jens Theisen wrote:
> "aaragon" <(E-Mail Removed)> writes:
>
> > typedef std::map<string,double> Map;
> > so when I need an unsigned int for example, I put an identifier in
> > front (size_t)Map[popSize]. This works but I thought it was a better
> > way to do this.

>
> Is there a reason why you can't use different maps? I can think of
> cases where you can't, or don't want to, but I suspect that you
> actually should better do.
>


Well, the only reason was to refer to all the parameters of the problem
with a single map. I did think about the possibility to having
different maps to hold different variable types but then I thought that
maybe there was a better way to do it.

> Frankly, I think that the language making it hard for you to follow
> your approach is a sign that you're trying to do the wrong thing.
>
> You want to store a variable popSize as a value of a map. Is there a
> reason why you can't use a proper variable: size_t popSize? Do you
> have an arbitrary number of those? How are they used?
>


I didn't want to store the variables in the proper way, because I think
that at some stage of the code I will be accesing the same variables
from different locations (and different objects will be accesing these
variables as well). Also, there are some variables that do not belong
to any single object.

> If you could post some code of what you're really trying to do, this
> would help a lot.
>
> > I never thought that having a map for different types was as
> > complicated as this.

>
> It's simple with boost::any, and for double, int and bool alone a
> union is also a possibility. However, this is most certainly not want
> you want to do.


I'll try this boost::any =)

>
> > Yes, I'm trying to write the code as optimal as possible from the
> > beginning. It is not that I have a big map.

>
> You know that early optimisation is the source of all evil, do you?
> But that's a different matter.
>


I didn't know this... why???????

> Jens


 
Reply With Quote
 
Jens Theisen
Guest
Posts: n/a
 
      09-21-2006
"aaragon" <(E-Mail Removed)> writes:

> Well, the only reason was to refer to all the parameters of the problem
> with a single map. I did think about the possibility to having
> different maps to hold different variable types but then I thought that
> maybe there was a better way to do it.


Do you have experience with dynamically typed languages such as Perl
or Python? In those, you do exactly what you're trying to do in C++.

You might not want to heed this advice, but I urge you: Let the type
system be your friend; don't use boost::any unless absolutely
necessary and rather use multiple maps, or even better, simple
variables as long as that's sufficient.

Don't cast around, especially not with C-style casts ( as in
(int)myvar ).

The type system is a feature of C++, not a nuisance. It pulls the
logic of your program together so that it doesn't fall apart.

> Also, there are some variables that do not belong
> to any single object.


Because there are global? Make them either global then, or have some
object that contains what's effectively global storage. Refactor it
when it gets too big.

> I'll try this boost::any =)


Resist!

> > You know that early optimisation is the source of all evil, do you?
> > But that's a different matter.
> >

>
> I didn't know this... why???????


Because

1. you will not be successful (you don't know what will make your
program slow when it will eventually be)

but

2. you will waste resources in the try and probably also compromise
other design goals such as correctness.

I know that it's difficult not to early optimisation, but I'm
convinced it's wise.

Regards,

Jens
 
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
An associative container jacob navia C Programming 21 11-21-2009 03:44 PM
Why "associative" in associative container? desktop C++ 5 06-26-2007 07:49 AM
Sortable associative container? Matthias =?ISO-8859-1?Q?K=E4ppler?= C++ 7 12-03-2004 01:12 AM
associative container T.Meitz C++ 2 02-17-2004 06:13 PM
std::container::iterator vs std::container::pointer Vivi Orunitia C++ 11 02-04-2004 08:09 AM



Advertisments