Re: C++ value from union structure using generic class
- From: "Arthur J. O'Dwyer" <ajonospam@xxxxxxxxxxxxxx>
- Date: Fri, 26 Jan 2007 12:12:04 -0500 (EST)
On Fri, 26 Jan 2007, Hunk wrote:
Hi
I am out of ideas in trying to solve the below issue. I have a union
structure which is stored in a map and indexed by a key. I need to
write a class to cache in the value stored in the structure. It could
be easily done by having a templatised class. But the guru's have
proclaimed that proliferation of classes is an issue.
If some particular mantra gets in the way of solving an actual
problem, it /is/ permitted to ignore the mantra, you know!
Now to solve this, I can have a generic class having a templatised
function say get_value to return the value stored in the union.
Stop. Arrgh. You're definitely going through some weird contortions
in your program, or maybe just in your description of your program.
If you ever hear yourself using more than one of the words "union",
"generic", "template", "overloaded", "pattern", "dispatch",
"inheritance" in a sentence, you should probably stop and rethink
what you're trying to do.
[snip more of the same]
Just bear with me if you have come this far.. a sample code is shown
below
// the union structure holding the value
union u_data {
int d_int_data;
float d_float_data;
void* d_user_def_data;
};
// templatised index class to identify the union structure which is
stored in a map
<template data_type>
class Index{
int key; // id associated with the union structure
}
That "<template data_type>" line is not C++ syntax, so I'm not sure
what you meant to write; but what you /should/ have written was
struct data {
int key; /* holds one of three values */
union {
int i;
float f;
void *vp;
} u;
};
[big snip]
*(reinterpret_cast<R*>(d_data.d_user_def_data));
I think you should be using a static_cast<R*> here, by the way.
I personally think of the C++ foo_casts as "the one with the shorter
name is more likely to be right".
static_cast > dynamic_cast > reinterpret_cast.
This woud work fine as it is. But i would want to ensure that if the
user is passing an index to get a union whcih is holding a float value
and in the get_value he passes accidentally an int , it should give a
compile time error.
Obviously you can't catch runtime errors at compile time. Consider
what should happen if the user writes
MyCache *m;
if (odd_perfect_exists())
m = new MyCache(3.14); // storing a float
else
m = new MyCache(42); // storing an int
MyCache.getvalue(new int); // try to retrieve an int
To return the user a compile time error i would have to know the type
he passed in the construction of the class, so that i could do some
trick by checking using trait classes to throw a compile time error.
any ideas on the same?
You need to read what the comp.lang.c FAQ has to say about unions,
and then read what the comp.lang.c++ FAQ says about templates. You're
coming up with really complicated anti-solutions to problems that
should be solved quickly and easily, either with the C-style
tag-and-union I showed you already, or with
template <typename T>
struct MyCache {
T *value;
};
// plus specializations for 'int' and 'float';
// compare "std::vector<bool>" in the C++ standard
-Arthur,
"when in doubt, read the FAQ"
.
- Follow-Ups:
- References:
- Prev by Date: Lint without annotations
- Next by Date: Re: Algorithm to find break in contiguity
- Previous by thread: C++ value from union structure using generic class
- Next by thread: Re: C++ value from union structure using generic class
- Index(es):
Relevant Pages
|