Jump to content

Welcome to Geeks to Go - Register now for FREE

Geeks To Go is a helpful hub, where thousands of volunteer geeks quickly serve friendly answers and support. Check out the forums and get free advice from the experts. Register now to gain access to all of our features, it's FREE and only takes one minute. Once registered and logged in, you will be able to create topics, post replies to existing threads, give reputation to your fellow members, get your own private messenger, post status updates, manage your profile and so much more.

Create Account How it Works
Photo

C++ quickie


  • Please log in to reply

#1
cainiskey

cainiskey

    New Member

  • Member
  • Pip
  • 7 posts
Hi,

Just looking for some inspiration.

I'm imp'ing an STL map with strings as the keys.
I need the data component to contain several data values, one of which can be int, bool, double, or string.
How would I go about this? A struct will contain the necessary data but it's the arbitrary variable type that gets me. Do I use void*? inheritance? And how do I go about assigning/accessing the data?

Any help will be greatly appreciated, this C++ business is driving me mad.
Cheers
~G
  • 0

Advertisements


#2
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
In C, the technique for doing this is to use a union:
http://www.cplusplus...data_types.html
  • 0

#3
cainiskey

cainiskey

    New Member

  • Topic Starter
  • Member
  • Pip
  • 7 posts
Ok, so I can use a union to hold the data. The problem I'm now facing is determining what kind of data it is when I'm putting it in. sizeof will differentiate between bool and double, but string and int have the same sizeof.

How do I figure out which variable to assign, using a put(string opt_name, T data) where opt_name is the key for the map and data is the variable I'm holding in the data portion (which is itself in this struct)?

struct opt_data{
bool is_simple;

union value{
int i;
double d;
string s;
bool b;
};
};

if (sizeof(data) == sizeof(double)) opt_data.value.d = data;

...and so on, but this will not work for string and int.

Thanks for your reply, please keep em coming!
~G
  • 0

#4
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
Why not just add an enum or something to store the current type?

enum data_type { IsInt, IsDouble, IsString, IsBool };

Then inside your struct with the union just add:

data_type type;

and use:

value.i = SomeIntegerValue
type = IsInt;

or:

if(type == IsBool) { DoSomethingToBool(value.b); }


You could also just accomplish this (though not as nicely) with:

#define IS_INT (0)
#define IS_DOUBLE (1)
etc

int type;
value.i = SomeIntegerValue
type = IS_INT;
  • 0

#5
cainiskey

cainiskey

    New Member

  • Topic Starter
  • Member
  • Pip
  • 7 posts
Thanks again,

The enum is a good idea; I was going to use 4 seperate bools to store isInt, isDouble etc etc...
I still don't see how I can determine what type it is when it's being stored though. put is a templated function:
template<typename T> put(string opt_name, T value, string opt_desc);
So it compiles with 4 different versions of this function(for bool,int,double,string), but as far as I know there is no direct way in C++ to determine what type T is. I could call put("-d",3,"this is an integer") but have no idea how to let the data struct know that it is an int just from this call. I can't change the signature of the function either, it HAS to take (string,T,string).
I know, I'm a total amateur.

Thanks for your help thus far, I'll leave you alone soon :whistling:
~G
  • 0

#6
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
Wait --- I am no longer sure of what you want to do. You want to pass the "value" field of the "opt_data" structure as the "value" parameter to the templated put function? And you want the function to determine what type 'value' is? Why don't you instead pass the whole struct, so that the function can simply query the 'type' parameter?
  • 0

#7
cainiskey

cainiskey

    New Member

  • Topic Starter
  • Member
  • Pip
  • 7 posts
It's for a school assignment, so I can't pass in the whole struct because of the following...

It's an "Option handler". If I create an Options object o then I have to be able to make the following calls:
o.put("-i", 8, "int option");
o.put("-d", 9.5, "double option");
o.put("-b", true, "bool option");
o.put("-s", string("foo"), "string option");
And then to retrieve them:
int i;
double d;
o.get("-i", i);
o.get("-d", d);
...
This is supposed to store the value previously stored linked to "-i" in int i (or "-d" in double d).
That's pretty much all they give me. I figured a map would be the best way to go about this, and I figured templating the put function would make sense (but by all means correct me on this), but I can't for the life of me figure out how to store and retrieve the data as the correct type. Clearly 9.5 can't be stored as an int, fine, I can store it inside my union inside my struct...but how does put know to assign 9.5 to the double variable inside the union? And how does 'get' assign the correct data type again?
It's starting to seem like my entire approach is flawed.

Thanks again
~G
  • 0

#8
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
You must forgive me for asking more clarifying questions --- do you want the object o to be able to hold an int, a double, a bool, and a string *simultaneously*? Or should it only hold one of the four at a time?

That is, if I call:

o.put("-i", 8, "int option");
o.put("-d", 9.5, "double option");

o.get("-i", i);

Would that be considered an error or a bad call? Or should the call to o.get() correctly return 8?

Another question: if I call:

o.put("-i", 8, "int option");
o.put("-i", 9, "int option");

o.get("-i", i);

will it return 9 correctly, or is this a bad call? That is, should the second call to o.put() 'overwrite' the first?

If it only has to hold one at a time, the union is the right way to do it. If all four, then you'll need to keep all four variable types around.

I also take it the first argument to put() is a flag consisting of the type of argument you are passing? If that is always so, then you don't need to worry about the issues of determining type like you had been talking about before --- just query the first argument, and if it's "-b", for example, then the second argument should be a bool! If it's "-d" then put() will interpret the second argument as a double! etc.

The third argument is a comment, and should be ignored?
  • 0

#9
cainiskey

cainiskey

    New Member

  • Topic Starter
  • Member
  • Pip
  • 7 posts
Forgive you? Forgive me for being dense!

I think you've solved my problem. I was assuming that the type being stored wasn't strictly tied to the letter option; i.e. you could have "-i",8,"int value" AND "-x",8,"another int value". Now I've re-read the assignment 11 or 12 times and I'm pretty sure you're right: All I have to do is query the first parameter to find out which type to store. The wording is damned ambiguous though!

Thanks so much for your help, it's most appreciated!
Cheers,
~G
  • 0

#10
Swandog46

Swandog46

    Malware Expert

  • Member
  • PipPipPipPip
  • 1,026 posts
  • MVP
No problem --- happy it helped! :whistling:
  • 0






Similar Topics

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

As Featured On:

Microsoft Yahoo BBC MSN PC Magazine Washington Post HP