Posted: Wed Nov 02, 2005 11:41 am Post subject: Possible with templates?
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
Property values are also always integral. The naive implementation
would be to store all properties in an int-to-int map, and let any
object hold any value for any property.
Unfortunately, maps are problematic for two simple reasons: size and
speed. The application needs to work with 100s of 1000s of objects,
and each object can have up to 12 properties (although most only have 4
or 5). It needs to be able to very very rapidly access basically every
property of every object, and not impose unreasonable memory
requirements. The performance testing I did basically ruled out maps
on this basis.
Now much of the time the properties required are known at compile time.
That is, I might have code like:
int color = object.property(property_color);
Basically, I need this to compile to code that isn't measurably slower
than a direct reference to a data member, e.g.:
int color = object.color;
Furthermore, in order to reduce memory requirements, I've worked out
how pack all the possible properties into either 16 or 8 bit integers,
some of them signed, some of them unsigned.
I also know that each object has a key property - "type" - that
determines which other properties make sense for an object. So an
object of type, say, "sound" doesn't have a color, whereas an object of
type "car" would.
With this in mind I came up with a system of macros that allows me to
do the following:
template <bool get>
inline void getset(Object& obj, int prop, int& value, int type = 0)
{
if (type == 0) type = obj.props[0];
switch (type)
{
case objectSound:
GETSETPROP3(
int16_t, propPitch,
uint16_t, propDuration,
uint16_t, propVolume);
case objectCar:
GETSETPROP4(
uint16_t, propColor,
uint8_t, propCylinders,
uint8_t, propDoors,
uint16_t, propEngineSize);
// etc.etc.;
}
}
I've comfirmed by looking at the disassembly and some performance
testing that this does exactly what I want for cases where both the
object type and property id are known at compile time, and for cases
where one or the other or both are not (in fact, it's damn impressive
the sort of optimizations compilers can do in this regard!). The 'both
unknown at compile time' scenario pretty much only occurs when
serializing, but even this can't afford to be as slow as a std::map
lookup.
The part I don't like about it is the GETSETPROP# macros, which need to
be defined for every number between 1 and 12, and use some slightly
ugly casting, e.g.:
I accept the casting will be necessary one way or another (or you could
cheat and use a union), but this is really just a method of packing as
much data as possible into a limited block of space.
The obvious question is how much of this can be done with just template
meta-programming? I know you can define type chains and the like, but
I couldn't really see how it would help me here.
If I can scrap the macros entirely I would be very happy, but
everything I've tried so far has failed to get me anywhere.
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
Property values are also always integral. The naive implementation
would be to store all properties in an int-to-int map, and let any
object hold any value for any property.
Unfortunately, maps are problematic for two simple reasons: size and
speed. The application needs to work with 100s of 1000s of objects,
and each object can have up to 12 properties (although most only have 4
or 5). It needs to be able to very very rapidly access basically every
property of every object, and not impose unreasonable memory
requirements. The performance testing I did basically ruled out maps
on this basis.
100,000 * 12 * sizeof(int) = 4.5MB (assuming int is 4 bytes). If efficiency
is so important, why not just put all the properties into an array and
directly access them? With the space overhead of a map, there probably
isn't much difference in memory use. Indeed, it may well take less memory.
Do you know in advance which properties are pertinent to each object?
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
This is actually the quite uninteresting challenge of educating you
about proper use of C or C++. What you describe are structures, plain
and simple. "properties" are just fields, you aren't keying them by
integers, but by symbolic names, and that's the same as field labels.
You also describe simple static typing, which is built-in to C++. Your
structures may also form an inheritance hierarchy or you may need to
build a union of (some of) them, but the need for that is not clear from
your description.
Quote:
The performance testing I did [...]
and some performance testing [...]
Way too much performance testing and way too little design. If you
worked out what your program is actually supposed to do, the right data
structure would come naturally. Instead you "designed" a final solution
to all conceivable problems by modelling everything in terms of
"properties" and "objects", both of which are just hollow phrases. If
you follow this path, you just end up with an ugly and ill-designed
programming language, but still no application. (You may have a genuine
need for a language different from C++. If so, don't invent one, _use_
one instead.)
Posted: Fri Nov 04, 2005 11:01 am Post subject: Re: Possible with templates?
Ian McCulloch wrote:
Quote:
wizofaus (AT) hotmail (DOT) com wrote:
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
Property values are also always integral. The naive implementation
would be to store all properties in an int-to-int map, and let any
object hold any value for any property.
Unfortunately, maps are problematic for two simple reasons: size and
speed. The application needs to work with 100s of 1000s of objects,
and each object can have up to 12 properties (although most only have 4
or 5). It needs to be able to very very rapidly access basically every
property of every object, and not impose unreasonable memory
requirements. The performance testing I did basically ruled out maps
on this basis.
100,000 * 12 * sizeof(int) = 4.5MB (assuming int is 4 bytes). If efficiency
is so important, why not just put all the properties into an array and
directly access them? With the space overhead of a map, there probably
isn't much difference in memory use. Indeed, it may well take less memory.
Do you know in advance which properties are pertinent to each object?
Yes, but there are nearly 100 different properties that are possible
across all objects, and I want my code to be able to generically
attempt to access any property from any value, even though, in the
current design, every object type only requires a small subset of the
total available property types.
And even 4.5 Mb is more than I'd like to use, given that this will not
represent the entire memory footprint, and I would like to be able to
run several instances of the same application. Currently I'm at ~2 Mb,
and I'd like to keep it that way.
Posted: Fri Nov 04, 2005 11:03 am Post subject: Re: Possible with templates?
Udo Stenzel wrote:
Quote:
wizofaus (AT) hotmail (DOT) com <wizofaus (AT) hotmail (DOT) com> schrieb:
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
This is actually the quite uninteresting challenge of educating you
about proper use of C or C++. What you describe are structures, plain
and simple. "properties" are just fields, you aren't keying them by
integers, but by symbolic names, and that's the same as field labels.
You also describe simple static typing, which is built-in to C++. Your
structures may also form an inheritance hierarchy or you may need to
build a union of (some of) them, but the need for that is not clear from
your description.
I'm well aware of many other ways the problem could be solved - in
nearly 15 years of C/C++ programming, I've seend and used almost every
conceivable data structure in existence. I'm quite happy with the
solution I have, I'm just curious if there's a slightly neater way to
implement it.
Quote:
The performance testing I did [...]
and some performance testing [...]
Way too much performance testing and way too little design.
I initially spent 12 months (on and off) designing the basic data
structure - working out what object types are required and what
properties each type requires.
But I have some real performance requirements that just are not
satisfied but any other option I've tried out so far.
Quote:
Instead you "designed" a final solution
to all conceivable problems by modelling everything in terms of
"properties" and "objects", both of which are just hollow phrases.
True, but they adequately and accurately represent all the data I
require and the concepts I am modelling. What I need is a compact and
efficient way to store them in memory, that allows very rapid
iteration.
The reason C++ is ideal for what I want is that I can entirely separate
the code that requires access to the objects and their properties from
the data structures used to store them - in the performance testing I
did, I never had to change the application code - only the data
definitions and the accessor functions. Few other languages would make
that straightforward.
Posted: Fri Nov 04, 2005 11:09 am Post subject: Re: Possible with templates?
Ian McCulloch wrote:
Quote:
wizofaus (AT) hotmail (DOT) com wrote:
Ok, this is really just a "is there anyone who thinks this
is a worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all
the objects in my data structure have their properties
referenced by integer ids. Property values are also always
integral. The naive implementation would be to store all
properties in an int-to-int map, and let any object hold any
value for any property.
Unfortunately, maps are problematic for two simple reasons:
size and speed. The application needs to work with 100s of
1000s of objects, and each object can have up to 12
properties (although most only have 4 or 5). It needs to be
able to very very rapidly access basically every property of
every object, and not impose unreasonable memory
requirements. The performance testing I did basically ruled
out maps on this basis.
100,000 * 12 * sizeof(int) = 4.5MB (assuming int is 4 bytes).
If efficiency is so important, why not just put all the
properties into an array and directly access them? With the
space overhead of a map, there probably isn't much difference
in memory use. Indeed, it may well take less memory. Do you
know in advance which properties are pertinent to each object?
If I understand correctly, he wants some sort of generic access;
given a (variable) property id, he wants to access the correct
property.
The most direct way of implementing this is to just use virtual
functions get and set:
class Object
{
public:
virtual ~Object() {}
virtual int get( int propertyId ) const = 0 ;
virtual void set( int propertyId, int newValue ) = 0 ;
} ;
Each concrete type then derives from Object, defines whatever
properties it needs as data members, and provides an
implementation of get and set to access the correct member; a
naíve implementation might use a switch, but double dispatch
through an object in a map could also be used:
It would still be necessary in each derived object to define the
template specializations for the relevant properties. And to
initialize the static maps. It should be relatively easy to
generate this code automatically, however. (Some form of
indirection is probably needed, as I don't think you can
explicitly specialize a member function template of a
non-template class. Or perhaps you define the derived class as
a template specialization, templated on the propertyId.)
An alternative solution would be to declare virtual getters and
setters for all of the possible attributes in the base class,
with a default implementation of generating an error. When
generic access is needed (which is probably the exception --
when getting or setting a color, the code knows that it is
dealing with color), a simple vector of pointers to abstract
getter/setter objects like the above could be used. This would
be the fastest solution, but it results in an extremely heavy
base class interface.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the
objects
in my data structure have their properties referenced by integer ids.
Property values are also always integral. The naive implementation
would be to store all properties in an int-to-int map, and let any
object hold any value for any property.
Some ideas to try:
1) Use virtual functions
class object
{
public:
virtual int get_property(int key)
{
throw no_such_property();
}
};
class vehicle : public object
{
int m_colour, m_cylinders;
public:
...
int get_property(int key)
{
switch(key)
{
case colour: return m_colour;
case cylinders: return m_cylinders;
default: return object::get_property(key);
}
};
};
class car : public vehicle
{
public:
...
int get_property(int key)
{
switch(key)
{
case wheels: return 4;
default: return vehicle::get_property(key);
};
}
};
2) Store an array of std::pair<int,int> for each object. Use a binary
search to locate the property you want and read off the value.
Posted: Sat Nov 05, 2005 6:30 pm Post subject: Re: Possible with templates?
kanze wrote:
Quote:
Ian McCulloch wrote:
100,000 * 12 * sizeof(int) = 4.5MB (assuming int is 4 bytes).
If efficiency is so important, why not just put all the
properties into an array and directly access them? With the
space overhead of a map, there probably isn't much difference
in memory use. Indeed, it may well take less memory. Do you
know in advance which properties are pertinent to each object?
If I understand correctly, he wants some sort of generic access;
given a (variable) property id, he wants to access the correct
property.
The most direct way of implementing this is to just use virtual
functions get and set:
Tried that - not efficient enough. Basically, I can't really afford
any unnecessary indirection or memory allocation/deallocation. My
"objects" are just lumps of data really - they don't have any behaviour
per se (this is basically because determining what to do with one
particular object depends heavily on the surrounding objects, so the
logic has to be handled by the container, not the objects themselves).
I really can't afford a solution that's any slower than my current one,
so I was just hoping maybe there was a cleaner way of the defining how
to pack the properties into each object.
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
Property values are also always integral. The naive implementation
would be to store all properties in an int-to-int map, and let any
object hold any value for any property.
....
Posted: Sat Nov 05, 2005 6:41 pm Post subject: Re: Possible with templates?
[email]wizofaus (AT) hotmail (DOT) com[/email] () wrote (abridged):
Quote:
The obvious question is how much of this can be done with just template
meta-programming?
It sounds like you have nested switch statements, the first testing the
object's type and the second the property. The tests need to be dynamic
because the tested values aren't always known at compile time.
I don't see how to make a switch with templates. I expect it is possible
to synthesis a linear search using type chains and the like. Probably it
is possible to synthesis a binary search, too. The big question is whether
the compiler will be able to optimise it when the values are known. You
could end up with a recursive search, eg:
int Child::get( int property ) {
if (property < c_property) ?
return Base1::get( property );
else
return Base2::get( property );
}
where c_property is a compile time constant. It might be worth trying. A
good compiler could inline everything into a big if-else tree, and when
property is known at compile time it could do all the comparisons at
compile time too, leaving a simple return statement.
Whether the binary search is slower than the switch statement if the
property is not a compile time constant I don't know. You'd need to
measure. The number of cases is small, and a direct jump can be much
faster than an indirect jump, and a switch statement will need a few tests
to ensure the argument is in range anyway. Some compilers might implement
the switch with a linear or binary search anyway.
It sounds to me like it would be worth a try, at least for the second
switch. For the first switch I gather you have more cases, so a
switch+cast may be better. As James Kanze says you could also use a
virtual function call, but I suspect that would be harder for the compiler
to optimise.
I'm not going to write real code, but ideally a declaration would look
like:
struct ObjectCar :
Child
Child
Base
Base<propCylinders,int8_t> >,
Child<propDoors,
Base
Base<propEngineSize,int16_t> > > {
};
only with some means to disambiguate the base classes. I suppose there's a
danger this would be less space efficient than your version.
I accept the casting will be necessary one way or another (or you could
cheat and use a union), but this is really just a method of packing as
much data as possible into a limited block of space.
The obvious question is how much of this can be done with just template
meta-programming? I know you can define type chains and the like, but
I couldn't really see how it would help me here.
The following uses multiple inheritance to solve the problem. Only
compile time properties are available, but looking through your
original function this seems to be confirmed by the type parameter
anyway.
#include <iostream>
template <int ID>
struct property{
property() : value(0){}
int value;
int get() const
{
return value;
}
void set ( int v)
{
value = v;
}
};
// for how both functions work see below
template <int ID,typename Object>
int get_property (Object const & in)
{
property<ID> const & t = static_cast<property(in);
return t.get() ;
}
template <int ID,typename Object>
void set_property (Object & in, int value)
{
property<ID> & t = static_cast<property(in);
t.set(value) ;
}
// some 'objects' comprised of various properties
struct my_object1 : property<1>,property<2>{};
struct my_object2 : property<5>,property<6>,property<7>{};
Ok, this is really just a "is there anyone who thinks this is a
worthwhile challenge" sort of query!
Basically, I'm working on data structure design whereby all the objects
in my data structure have their properties referenced by integer ids.
Property values are also always integral. The naive implementation
would be to store all properties in an int-to-int map, and let any
object hold any value for any property.
<snip>
Quote:
With this in mind I came up with a system of macros that allows me to
do the following:
template <bool get
inline void getset(Object& obj, int prop, int& value, int type = 0)
{
if (type == 0) type = obj.props[0];
switch (type)
{
case objectSound:
GETSETPROP3(
int16_t, propPitch,
uint16_t, propDuration,
uint16_t, propVolume);
case objectCar:
GETSETPROP4(
uint16_t, propColor,
uint8_t, propCylinders,
uint8_t, propDoors,
uint16_t, propEngineSize);
// etc.etc.;
}
}
I think I would prefer virtual functions to switching based upon a type
enumeration. This makes the object-model extensible, and I think more
efficient (though, you should check that on your particular compiler).
Also watch out for alignment issues: you may not necessarily get a
speed/space improvement just because you use 8 bits instead of 16.
The answer to your question is yes, you can use templates, and I think
they are a preferable solution to macros. Here is a complete solution
based upon virtual functions, that uses templates to construct
property-lists:
#include
#include <stdexcept>
class NoSuchProperty : public std::out_of_range
{
public:
NoSuchProperty() : std::out_of_range("NoSuchProperty") { }
};
class object
{
public:
virtual short &operator[](int x)=0;
virtual short operator[](int x) const=0;
};
class empty { };
template<int I, class Tail=empty>
struct int_list
{
static int const value = I;
typedef Tail tail_type;
};
template<class Value, class List>
class property_list
{
Value value;
property_list<Value, typename List::tail_type> tail;
public:
Value &property(int k)
{
return k == List::value ? value :
tail.property(k);
}
const Value &property(int k) const
{
return k == List::value ? value :
tail.property(k);
}
};
template<class Value>
class property_list<Value,empty>
{
public:
Value &property(int i)
{
throw NoSuchProperty(); // Maybe return 0 instead?
}
template<typename IntList>
class property_object : public object
{
property_list<short, IntList> m_property_list;
public:
short &operator[](int k) { return m_property_list.property(k); }
short operator[](int k) const { return m_property_list.property(k); }
};
template<int I1> class int_list_1 : public int_list<I1> { };
template<int I1, int I2> class int_list_2 : public int_list<I1,
int_list { };
template<int I1, int I2, int I3> class int_list_3 : public int_list<I1,
int_list_2 { };
// etc
Posted: Mon Nov 07, 2005 9:36 am Post subject: Re: Possible with templates?
kwikius wrote:
Quote:
wizofaus (AT) hotmail (DOT) com wrote:
[cut]
I accept the casting will be necessary one way or another (or you could
cheat and use a union), but this is really just a method of packing as
much data as possible into a limited block of space.
The obvious question is how much of this can be done with just template
meta-programming? I know you can define type chains and the like, but
I couldn't really see how it would help me here.
The following uses multiple inheritance to solve the problem. Only
compile time properties are available, but looking through your
original function this seems to be confirmed by the type parameter
[cut]
The previous code couldnt be used in a list of objects. The following
code (needs http://www.boost.org libs) extended from the code above
allows this:
// use MI to inherit your object
// from required properties
template <int ID>
struct property{
static const int id = ID;
property() : value(0){}
int value;
int get() const
{
return value;
}
void set(int v)
{
value = v;
}
};
// error function
struct invalid_property : std::out_of_range{
invalid_property()
: std::out_of_range(
"property out of range"
){}
};
// check if a particular Object-type has property N
template <typename Object, int ID>
struct has_property : boost::is_base_of<
property
Quote:
{};
// get_property is called on various Objects
// this overload for valid objects
template <int ID,typename Object>
inline
typename boost::enable_if<
has_property
int
Quote:
::type
get_property (Object const & in)
{
property<ID> const& t
= static_cast<property(in);
return t.get() ;
}
// get_property needs to be instantiated
// for Objects that cant be cast to property<ID>
// in object_impl below
// but will fail if actually called
template <int ID,typename Object>
inline
typename boost::disable_if<
has_property
int
{
property<ID>& t
= static_cast<property(in);
t.set(value) ;
}
// needs to be instantiated
// by object_impl below,
// but will fail if called
template <int ID,typename Object>
inline
typename boost::disable_if<
has_property
void
Quote:
::type
set_property (Object & in, int value)
{
throw invalid_property();
}
// base class for containerable objects
struct object{
virtual int get(int property_id)const =0;
virtual void set(int property_id,int value) =0;
virtual ~object(){}
// object implementation,
// derive class with properties from here
// usin CRTP
// so derived class can be
// used in object* containers
// (Theoretically CRTP removes
// some virtual function call overhead)
template <typename D>
struct object_impl : object{
// allow D to create more efficient
// get_impl function as in my_object3 below
int get(int property_id)const{
D const & d
= static_cast<D const &>(*this);
return d.get_impl(property_id);
}
// this version needs a case for all potential properties
// (Actually if all cases are in step then lookup implementation
// is constant time [just jump offset]
// irrespective of number of values in VC7.1 at least)
int get_impl(int property_id) const
{
D const & d
= static_cast<D const &>(*this);
int result =0;
switch (property_id){
case object::prop1:
result = get_property<object::prop1>(d);
break;
case object::prop2:
result = get_property<object::prop2>(d);
break;
case object::prop3:
result = get_property<object::prop3>(d);
break;
case object::prop4:
result = get_property<object::prop4>(d);
break;
case object::prop5:
result = get_property<object::prop5>(d);
break;
case object::prop6:
result = get_property<object::prop6>(d);
break;
case object::prop7:
return get_property<object::prop7>(d);
default:
throw invalid_property();
}
return result;
}
// allow derived to create more efficient
// set_impl function as in object3 below
void set(int property_id,int value)
{
D & d = static_cast<D &>(*this);
d.set_impl(property_id,value);
}
// this version needs statements for
// all properties
void set_impl(int property_id,int value)
{
D& d = static_cast<D&>(*this);
switch (property_id){
case object::prop1:
set_property<object::prop1>(d,value);
break;
case object::prop2:
set_property<object::prop2>(d,value);
break;
case object::prop3:
set_property<object::prop3>(d,value);
break;
case object::prop4:
set_property<object::prop4>(d,value);
// throw invalid_property();
break;
case object::prop5:
set_property<object::prop5>(d,value);
break;
case object::prop6:
set_property<object::prop6>(d,value);
break;
case object::prop7:
set_property<object::prop7>(d,value);
break;
default:
throw invalid_property();
}
}
};
// some example 'objects' comprised of various properties
// They also need to be derived from object_impl<T>
//if they are meant to be 'objects'
// One obvious refinement. In my_object3 smaller
// size of lookup for get_impl is achieved by
// over-riding get_impl, set_impl functions
// because Only look up of PA, PB,PC is required
// Would need to add versions of the class
// for different numbers of properties
// No speed up expected but maybe smaller size
// assuming object_impl functions not instantiated
// for these versions. Actually
// I think ths may be slower than the version in
// object_impl though!
template <int PA,int PB, int PC>
struct my_object3 :
property<PA>,
property<PB>,
property<PC>,
object_impl<my_object3>{
int get_impl(int property_id) const
{
int result=0;
switch (property_id){
case PA:
result = get_property<PA>(*this);
break;
case PB:
result = get_property<PB>(*this);
break;
case PC:
result =get_property<PC>(*this);
break;
default:
throw invalid_property();
}
return result;
}
void set_impl(int property_id, int value)
{
switch (property_id){
case PA:
set_property<PA>(*this,value);
break;
case PB:
set_property<PB>(*this,value);
break;
case PC:
set_property<PC>(*this,value);
break;
default:
throw invalid_property();
}
}
};
// further encapsulation is cheap and easy
struct my_object4 :
my_object3<object::prop4,object::prop1,object::prop7>{};
If I can scrap the macros entirely I would be very happy, but
everything I've tried so far has failed to get me anywhere.
Having looked into it a bit more ( via my two previous posts in this
thread), I reckon that your current solution is pretty well optimal. It
seems to work at least 2x as fast as my polymorphic code at least where
constants are known at compile time (otoh my rt non-polymorpic code
works as fast), so if it works for you, I guess you should ignore the
stylists and live with it. . I think that you could do pretty much
the same by slicing a class built up in parts, at least for the code in
your post. Also I wonder whether a design in which one 'object' may
have a sound property but no sound option and another a colour but no
sound option couldnt be improved...
100,000 * 12 * sizeof(int) = 4.5MB (assuming int is 4
bytes). If efficiency is so important, why not just put
all the properties into an array and directly access them?
With the space overhead of a map, there probably isn't
much difference in memory use. Indeed, it may well take
less memory. Do you know in advance which properties are
pertinent to each object?
If I understand correctly, he wants some sort of generic
access; given a (variable) property id, he wants to access
the correct property.
The most direct way of implementing this is to just use
virtual functions get and set:
Tried that - not efficient enough. Basically, I can't really
afford any unnecessary indirection or memory
allocation/deallocation. My "objects" are just lumps of data
really - they don't have any behaviour per se (this is
basically because determining what to do with one particular
object depends heavily on the surrounding objects, so the
logic has to be handled by the container, not the objects
themselves).
I really can't afford a solution that's any slower than my
current one, so I was just hoping maybe there was a cleaner
way of the defining how to pack the properties into each
object.
I'm not sure I understand your current solution. I had the
impression that you were using a switch -- depending on the
underlying hardware, a virtual function may be just as fast, or
even faster (or a lot slower -- it depends on the hardware).
That doesn't necessarily mean that it is the "correct" solution
in every case. What you are basically doing is using
discriminate unions, and there are cases where that is an
appropriate solution, even if there is no direct support for it
in C++ (except for the special guarantee in §9.2/16). While
it's rare that the choice between discriminate unions and an
inheritance hierarchy will make a significant difference in
terms of run-time, your statement that "what to do with one
particular object depends heavily on the surrounding objects"
suggests very strongly that discriminate unions are the
appropriate solution, or at least a solution which should be
considered.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum