By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,830 Members | 1,746 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,830 IT Pros & Developers. It's quick & easy.

Suitable data structure for a "context sensitive" 3-tuple?

P: n/a
Hi,

I want to store data in a 3-tuple {a,b,c}.
Element a is an enumeration, and element c is an enumeration which is
specific (i.e. determined) by a.

An example will help clarify further. I give two examples, one of a
valid instance, and the other, an invalid instance.

typedef enum { bovine, gamebird, seafood } general_meat ;

Note: each of the elements above is a category of its own. I can
further partition the seafood category to yield the following grouping:

typedef enum { scallops, lobster, cod, prawn, salmon} seafood ;
class Meal {
general_meat m ;
bool cook_first ;
X data_type_that_will_accept_specific_types_of_gener al_meat_m ;
}

I hope the illustration above provides some illumination on the problem.
class Meal will (obviously?) have to be a template class - but I
don't know how to enforce X to be a subset (i.e. a permissable type)
determined by m.

I look forward to any ideas for a possible solution. Thanks

Jul 23 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a


Susan Baker wrote:
Hi,

I want to store data in a 3-tuple {a,b,c}.
Element a is an enumeration, and element c is an enumeration which is
specific (i.e. determined) by a.

An example will help clarify further. I give two examples, one of a
valid instance, and the other, an invalid instance.

typedef enum { bovine, gamebird, seafood } general_meat ;

Note: each of the elements above is a category of its own. I can further
partition the seafood category to yield the following grouping:

typedef enum { scallops, lobster, cod, prawn, salmon} seafood ;
class Meal {
general_meat m ;
bool cook_first ;
X data_type_that_will_accept_specific_types_of_gener al_meat_m ;
}

I hope the illustration above provides some illumination on the problem.
class Meal will (obviously?) have to be a template class - but I don't
know how to enforce X to be a subset (i.e. a permissable type)
determined by m.

I look forward to any ideas for a possible solution. Thanks


Ok. Here are the two examples (of objects) I promised earlier:

meal1 { seafood, no, scallops } // <- valid
meal2 { bovine, yes, scallops } //<- invalid
Jul 23 '05 #2

P: n/a


Susan Baker wrote:
Hi,

I want to store data in a 3-tuple {a,b,c}.
Element a is an enumeration, and element c is an enumeration which is
specific (i.e. determined) by a.

An example will help clarify further. I give two examples, one of a
valid instance, and the other, an invalid instance.

typedef enum { bovine, gamebird, seafood } general_meat ;

Note: each of the elements above is a category of its own. I can
further partition the seafood category to yield the following grouping:

typedef enum { scallops, lobster, cod, prawn, salmon} seafood ;
class Meal {
general_meat m ;
bool cook_first ;
X data_type_that_will_accept_specific_types_of_gener al_meat_m ;
}

I hope the illustration above provides some illumination on the problem.
class Meal will (obviously?) have to be a template class - but I
don't know how to enforce X to be a subset (i.e. a permissable type)
determined by m.

I look forward to any ideas for a possible solution. Thanks


What is wrong with inheritance? Make
data_type_that_will_accept_specific_types_of_gener al_meat_m a pointer
to a general_meal. Derive bovine, gamberid and seafood from
general_meal.

dan

Jul 23 '05 #3

P: n/a


Dan Cernat wrote:

Susan Baker wrote:
Hi,

I want to store data in a 3-tuple {a,b,c}.
Element a is an enumeration, and element c is an enumeration which is
specific (i.e. determined) by a.

An example will help clarify further. I give two examples, one of a
valid instance, and the other, an invalid instance.

typedef enum { bovine, gamebird, seafood } general_meat ;

Note: each of the elements above is a category of its own. I can
further partition the seafood category to yield the following grouping:

typedef enum { scallops, lobster, cod, prawn, salmon} seafood ;
class Meal {
general_meat m ;
bool cook_first ;
X data_type_that_will_accept_specific_types_of_gener al_meat_m ;
}

I hope the illustration above provides some illumination on the problem.
class Meal will (obviously?) have to be a template class - but I
don't know how to enforce X to be a subset (i.e. a permissable type)
determined by m.

I look forward to any ideas for a possible solution. Thanks

What is wrong with inheritance? Make
data_type_that_will_accept_specific_types_of_gener al_meat_m a pointer
to a general_meal. Derive bovine, gamberid and seafood from
general_meal.

dan


Is general_meal a new class, or did you mean general_meat ?. I can see
where you're going with the inheritence suggestion. I could have a
heirarchy like:

meat
|
-------------------------
| | |
bovine gamebird seafood
and then sub-class each one of them accordingly. This is one way of ding
it - it also means a lot of coding - with all its attendant problems. I
was wondering if there was a way of applying generic programming
philosophy so I could have one generic factory that produces each of
these groupings (bovine, gamebird etc).

When using any of these meat derived classes (which should really be
abstract - since they are classifications), the derived class can only
instantiate with meaningful values, so that if I ask for a seafood Meal,
I do not end up with raw pork (for instance0. since pork is not a valid
member (enumeration item if you like) for the class seafood. I know all
of this can be done using inheritance and judious inspection of types
being passed in the class constructor etc - but this is not easily
extendable, for example, if I decide to allow new items to be part of
the seafood category, I have an awful lot of refactoring to do - I was
just wondering if there was a way of writing this in a generic way (if
not all, then at least some of it).

Jul 23 '05 #4

P: n/a
Susan,

I took a look at your second post

meal1 { seafood, no, scallops } // <- valid
meal2 { bovine, yes, scallops } //<- invalid

why would you want to do this? Pass in the scallops and that is all. No
need for validation. This is using inheritance. So, before talking
more, what is the exact problem you are trying to solve? So far you are
asking help in implementing _a_ solution, but what is your problem?
There may be better ways to solve it.

dan

Jul 23 '05 #5

P: n/a


Dan Cernat wrote:
Susan,

I took a look at your second post

meal1 { seafood, no, scallops } // <- valid
meal2 { bovine, yes, scallops } //<- invalid

why would you want to do this? Pass in the scallops and that is all. No
need for validation. This is using inheritance. So, before talking
more, what is the exact problem you are trying to solve? So far you are
asking help in implementing _a_ solution, but what is your problem?
There may be better ways to solve it.

dan


Hi Dan,

Just FYI, the examples I gave was not pseudocode (i.e. I was not passing
anything to the meal types). basically, what I meanto say was that a
valid meal (meal1), could comprise of the following "properties :

{
seafood /*food category*/,
no /*no cooking reqd b4 consumption*/,
scallops /* the specific food type */
}

In the second example I gave, the object was invalid because scallops do
not belong to the bovine food category. The actual problem statement is
too domain specific (i.e. requires too much speciliazed domain
knowledge) to go into detail here - it will simply further obfuscucate
the problem, besides, my boss is not likely to be too pleased with me
discussing this here (we've signed an NDA etc ...). However, the
description I gave is accurate. The more I think about it, the more I am
convinced to keep things simple. I think the inheritance route is the
way forward - once I've got that working, I'll look to "generalize" the
code later.

Thanks for your help anyhows..

Jul 23 '05 #6

P: n/a


Susan Baker wrote:
Dan Cernat wrote:
Susan,

I took a look at your second post

meal1 { seafood, no, scallops } // <- valid
meal2 { bovine, yes, scallops } //<- invalid

why would you want to do this? Pass in the scallops and that is all. No
need for validation. This is using inheritance. So, before talking
more, what is the exact problem you are trying to solve? So far you are
asking help in implementing _a_ solution, but what is your problem?
There may be better ways to solve it.

dan


Hi Dan,

Just FYI, the examples I gave was not pseudocode (i.e. I was not passing
anything to the meal types). basically, what I meanto say was that a
valid meal (meal1), could comprise of the following "properties :

{
seafood /*food category*/,
no /*no cooking reqd b4 consumption*/,
scallops /* the specific food type */
}

In the second example I gave, the object was invalid because scallops do
not belong to the bovine food category.

[snip]

Hi Susan,

scallops could be only seafood. There is no need to have the food
category in the meal. This way, the meals are always valid:
class meal
{
private:
bool cooked;
Food* food; /* the specific food type */
public:
meal(bool Cooked, Food* SpecificFood)
{
cooked = Cooked;
food = SpecificFood;
}

FoodCateg GetFoodCategory()
{
food->GetCategory();
}
};
meal m1(false, new Scallops);
meal m2(true, new GroundMeat);

How you store the category inside the Food class is a different story.
It could be a member variable or an inheritance chain or a templated
class. your call.

dan

Jul 23 '05 #7

P: n/a


Dan Cernat wrote:
FoodCateg GetFoodCategory()
{
food->GetCategory();
}


should be:

return food->GetCategory();

Jul 23 '05 #8

P: n/a
"Susan Baker" <sb****@no.spam.net> wrote in message
news:da**********@nwrdmz03.dmz.ncs.ea.ibs-infra.bt.com
Hi,

I want to store data in a 3-tuple {a,b,c}.
Element a is an enumeration, and element c is an enumeration which is
specific (i.e. determined) by a.

An example will help clarify further. I give two examples, one of a
valid instance, and the other, an invalid instance.

typedef enum { bovine, gamebird, seafood } general_meat ;

Note: each of the elements above is a category of its own. I can
further partition the seafood category to yield the following
grouping:
typedef enum { scallops, lobster, cod, prawn, salmon} seafood ;
class Meal {
general_meat m ;
bool cook_first ;
X data_type_that_will_accept_specific_types_of_gener al_meat_m ;
}

I hope the illustration above provides some illumination on the
problem. class Meal will (obviously?) have to be a template class -
but I don't know how to enforce X to be a subset (i.e. a permissable type)
determined by m.

I look forward to any ideas for a possible solution. Thanks


There may be more elegant ways to do it, but this seems to work:

enum general_meat { bovine, gamebird, seafood };

enum bovine_subtype { rump, sirloin, topside};
enum gamebird_subtype { pheasant, duck };
enum seafood_subtype { scallops, lobster, cod, prawn, salmon};

// general template class
template <general_meat gm>
struct SubTypeEnum
{};

// specialisations for each general_meat case

template<>
struct SubTypeEnum<bovine>
{
typedef bovine_subtype subtype;
};

template<>
struct SubTypeEnum<seafood>
{
typedef seafood_subtype subtype;
};

template<>
struct SubTypeEnum<gamebird>
{
typedef gamebird_subtype subtype;
};

template<general_meat gm>
class Meal : private SubTypeEnum<gm>
{
using typename SubTypeEnum<gm>::subtype;
bool cook_first ;
subtype s;
public:
Meal(bool cf, subtype st) : cook_first(cf), s(st)
{}
};

int main()
{
Meal<seafood> m1(true, scallops); // compiles

Meal<seafood> m2(true, rump); // won't compile
}

To add a new subtype, you just have to add it to the enum for that subtype.

To add a new type (say, pork), you need to:

1. Add pork to the general_meat enum.
2. Define a enum pork_subtype.
3. Add

template<>
struct SubTypeEnum<pork>
{
typedef pork_subtype subtype;
};
--
John Carson

Jul 23 '05 #9

P: n/a
"John Carson" <jc****************@netspace.net.au> wrote in message
news:da***********@otis.netspace.net.au

template<general_meat gm>
class Meal : private SubTypeEnum<gm>
{
using typename SubTypeEnum<gm>::subtype;
bool cook_first ;
subtype s;
public:
Meal(bool cf, subtype st) : cook_first(cf), s(st)
{}
};

I omitted the template parameter from the list of variables since I made no
use of it, but you probably want to add it back in:
template<general_meat gm>
class Meal : private SubTypeEnum<gm>
{
using typename SubTypeEnum<gm>::subtype;
general_meat meat_type;
bool cook_first ;
subtype s;
public:
Meal(bool cf, subtype st) : meat_type(gm), cook_first(cf), s(st)
{}
};
--
John Carson

Jul 23 '05 #10

P: n/a


John Carson wrote:
"Susan Baker" <sb****@no.spam.net> wrote in message
news:da**********@nwrdmz03.dmz.ncs.ea.ibs-infra.bt.com
Hi,

I want to store data in a 3-tuple {a,b,c}.
Element a is an enumeration, and element c is an enumeration which is
specific (i.e. determined) by a.

An example will help clarify further. I give two examples, one of a
valid instance, and the other, an invalid instance.

typedef enum { bovine, gamebird, seafood } general_meat ;

Note: each of the elements above is a category of its own. I can
further partition the seafood category to yield the following
grouping:
typedef enum { scallops, lobster, cod, prawn, salmon} seafood ;
class Meal {
general_meat m ;
bool cook_first ;
X data_type_that_will_accept_specific_types_of_gener al_meat_m ;
}

I hope the illustration above provides some illumination on the
problem. class Meal will (obviously?) have to be a template class -
but I don't know how to enforce X to be a subset (i.e. a permissable
type)
determined by m.

I look forward to any ideas for a possible solution. Thanks

There may be more elegant ways to do it, but this seems to work:

enum general_meat { bovine, gamebird, seafood };

enum bovine_subtype { rump, sirloin, topside};
enum gamebird_subtype { pheasant, duck };
enum seafood_subtype { scallops, lobster, cod, prawn, salmon};

// general template class
template <general_meat gm>
struct SubTypeEnum
{};

// specialisations for each general_meat case

template<>
struct SubTypeEnum<bovine>
{
typedef bovine_subtype subtype;
};

template<>
struct SubTypeEnum<seafood>
{
typedef seafood_subtype subtype;
};

template<>
struct SubTypeEnum<gamebird>
{
typedef gamebird_subtype subtype;
};

template<general_meat gm>
class Meal : private SubTypeEnum<gm>
{
using typename SubTypeEnum<gm>::subtype;
bool cook_first ;
subtype s;
public:
Meal(bool cf, subtype st) : cook_first(cf), s(st)
{}
};

int main()
{
Meal<seafood> m1(true, scallops); // compiles

Meal<seafood> m2(true, rump); // won't compile
}

To add a new subtype, you just have to add it to the enum for that subtype.

To add a new type (say, pork), you need to:

1. Add pork to the general_meat enum.
2. Define a enum pork_subtype.
3. Add

template<>
struct SubTypeEnum<pork>
{
typedef pork_subtype subtype;
};

This is the approach I'm looking for. Thanks very much - lots of "food
for thought" (pun intended !). Thanks

Jul 23 '05 #11

P: n/a
Susan Baker wrote:

Just FYI, the examples I gave was not pseudocode (i.e. I was not passing
anything to the meal types). basically, what I meanto say was that a
valid meal (meal1), could comprise of the following "properties :

{
seafood /*food category*/,
no /*no cooking reqd b4 consumption*/,
scallops /* the specific food type */
}


Why should a meal know to which category a specific food type belongs.
If it really needs to know, it can always ask the food type for this
information.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #12

P: n/a


Karl Heinz Buchegger wrote:
Susan Baker wrote:
Just FYI, the examples I gave was not pseudocode (i.e. I was not passing
anything to the meal types). basically, what I meanto say was that a
valid meal (meal1), could comprise of the following "properties :

{
seafood /*food category*/,
no /*no cooking reqd b4 consumption*/,
scallops /* the specific food type */
}

Why should a meal know to which category a specific food type belongs.
If it really needs to know, it can always ask the food type for this
information.


I can see your point. However, what I want to do is to create an
infrastructure that allows me to create valid object types, with minimal
room for error - I suppose a lot of this can be done using an abstract
factory design pattern - but I prefer the generic programming approach
using templates (if this is possible). Although the problem
representation may seem flawed from your point of view - I can assure
you that it is valid with the benefit of specific domain knowledge.
Valid objects need to be created so that they can be de-composed at a
later stage - an invalid object will lead to an equally invalid
decomposed object (or set of objects as the case may be).

Jul 23 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.