473,698 Members | 2,942 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Meta class programming question

I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with virtually
the exact same coding going on.

e.g.

class A
{
std::vector<B*> Bs;
public:
A() { blah; }

void SomeFunc_A() {blah blah blah};
}

class A
{
std::vector<C*> Cs;
public:
B() { blah; }

void SomeFunc_B() {blah blah blah};
}

and eventually one of the classes is a "terminal" in the sense it does not
continue the same abstract recursive process. My question is, is there any
way to automate this process? It seems I cannot use templates because I
cannot generate the proper method names are derived from the name of the
class?

i.e., I can't do something like

Metaclass template <class name, class subname>
class name
{
std::vector<sub name *> subname's';
public:
name() {blah}

void SomeFunc_@'name ' () { blah blah blah}
}

where say the 's' is appended to the subname literal and the @ appends the
string to the someFunc literal...

then I could do something like

Metaclass<A, B> and it produces the class Agiving above and Metaclass<B,C>
would produce B.
The reason I do this is because right now I have 7 files in my project that
all are virtually exactly the same as just 1(and how I got them was basicaly
using find and replace 3 times to turn the class into a "new" one that is
virtually identical with the other(excep ofcourse the coding is actualy the
same with different literals)).

My question is, is there any way in C++ to do something like this(I know my
code is not valid C++ code above but just giving some example). I just need
to generate a class from a meta class that also can change the method's
names that will be based on the name of the class.

Actually I will give a more concrete example that I actually kinda use in my
program:

class Score : public Base
{
public:
std::vector<Sta ff> Staffs;
int NumStaffs() { return (int)Staffs.siz e(); }
}

class Staff : public Base
{
public:
std::vector<Bar > Bars;
int NumBars() { return (int)Bars.size( ); }
}

class Bar : public Base
{
private:
public:
}

class Base
{
public:
std::vector<Pro perty> Properties;
int NumProperties() { return (int)Properties .size(); }
}

class Property
{
private:
public:
}

and I would want to access methods like:

Score.NumStaffs ();
Score.Staffs[0].NumBars();
etc...

I know I could make some general template where all methods across the
different classes would have the same name so I might have

Score.NumObject s(); which would return the number of objects in in the
vector in that object and(Staffs in this cass)
Score.Objects[0].NumObjects(); would return same as above but for the Bars.

The problem with this is I only need the recursiveness for about 5 classes
and that I want the naming to follow the modelling I'm using(modeling of
Score->Staff->Bar->Notes of music) else it might be confusing to remeber

Score.Objects[0].Objects[3].NumObjects(); is refering to

So thats the idea... as you can see most the classes are exactly the same
except for the naming of functions. I do see a problem now with my example
above about just adding 's' to the end... I wouldn't want Propertys but
Properties so there would have to be a way of creating logical english
literal names(i.e., replace ending y with ies when adding s), etc...

Anything that can do something like this out there? (would save me a lot of
work of having to to mess with 7 files that are identical except for naming
and potential other problems)

Jon

Sep 7 '05 #1
21 4072
On Wed, 7 Sep 2005 02:46:09 -0500, "Jon Slaughter" <Jo***********@ Hotmail.com>
wrote:
I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with virtually
the exact same coding going on.


Take a look at the ## preprocessor operator.

-dr
Sep 7 '05 #2
Jon Slaughter wrote:
I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with virtually
the exact same coding going on.

e.g.

class A
{
std::vector<B*> Bs;
public:
A() { blah; }

void SomeFunc_A() {blah blah blah};
}

class A
Do you mean

class B

?
{
std::vector<C*> Cs;
public:
B() { blah; }

void SomeFunc_B() {blah blah blah};
}
Without knowing what 'blah blah blah' is in each case, it's rather hard to
make any good suggestions, however, it seems that both classes could be
made into one template (given that 'blah blah blah's are very similar).

and eventually one of the classes is a "terminal" in the sense it does not
continue the same abstract recursive process.
Abstract recursive process? What are you talking about? There is nothing
abstract or recursive in the two classes presented.
My question is, is there any
way to automate this process?
Absolutely. Code generators are common as part of 4GL, IIRC.
It seems I cannot use templates because I
cannot generate the proper method names are derived from the name of the
class?
Why do you think that the names have to be different?
i.e., I can't do something like

Metaclass template <class name, class subname>
class name
{
std::vector<sub name *> subname's';
public:
name() {blah}

void SomeFunc_@'name ' () { blah blah blah}
}

where say the 's' is appended to the subname literal and the @ appends the
string to the someFunc literal...

then I could do something like

Metaclass<A, B> and it produces the class Agiving above and Metaclass<B,C>
would produce B.
It can be done with macros. But I honestly do *not* see why it would be
necessary.
The reason I do this is because right now I have 7 files in my project that
all are virtually exactly the same as just 1(and how I got them was basicaly
using find and replace 3 times to turn the class into a "new" one that is
virtually identical with the other(excep ofcourse the coding is actualy the
same with different literals)).
So, you want to refactor. That's good. Don't stop at automating the task
of naming your classes. If you really have a generic solution, make it
into a template and make sure you use it properly.
My question is, is there any way in C++ to do something like this(I know my
code is not valid C++ code above but just giving some example). I just need
to generate a class from a meta class that also can change the method's
names that will be based on the name of the class.
Yes. Use preprocessor macros. Or don't.
Actually I will give a more concrete example that I actually kinda use in my
program:

class Score : public Base
{
public:
std::vector<Sta ff> Staffs;
Why is this suddenly public?
int NumStaffs() { return (int)Staffs.siz e(); }
Why can't this function be named 'count'? If 'Score' always keeps the
count of 'Staff', IOW, if 'Score' is a collection of 'Staff', then there
is no misinterpretati on.
}

class Staff : public Base
{
public:
std::vector<Bar > Bars;
int NumBars() { return (int)Bars.size( ); }
And this function?... Name it 'count' and you're on your way to making
your classes generic.
}

class Bar : public Base
{
private:
public:
}

class Base
{
public:
std::vector<Pro perty> Properties;
int NumProperties() { return (int)Properties .size(); }
Again...
}

class Property
{
private:
public:
}

and I would want to access methods like:

Score.NumStaffs ();
Score.Staffs[0].NumBars();
So, you're going to give the _implementation _detail_ *public* access
specifier? That's not good.
etc...

I know I could make some general template where all methods across the
different classes would have the same name so I might have

Score.NumObject s(); which would return the number of objects in in the
vector in that object and(Staffs in this cass)
Score.Objects[0].NumObjects(); would return same as above but for the Bars.
But that's bad. You shouldn't access the 'Objects' collection directly.
The problem with this is I only need the recursiveness
There is no *recursiveness* here. There is only _nestedness_.
for about 5 classes
and that I want the naming to follow the modelling I'm using(modeling of
Score->Staff->Bar->Notes of music) else it might be confusing to remeber

Score.Objects[0].Objects[3].NumObjects(); is refering to
Yes, that _is_ confusing. Why do you think you'd need that? I would
only think that you might pass

Score.Object[i]

into some function where you'd use

MyObject.Object[j]

which in the context won't be confusing and will be absolutely clear
*what* it refers to.
So thats the idea... as you can see most the classes are exactly the same
except for the naming of functions. I do see a problem now with my example
above about just adding 's' to the end... I wouldn't want Propertys but
Properties so there would have to be a way of creating logical english
literal names(i.e., replace ending y with ies when adding s), etc...

Anything that can do something like this out there? (would save me a lot of
work of having to to mess with 7 files that are identical except for naming
and potential other problems)


Something like

#define DECLARE_CLASS(n ame,content) class name { \
std::vector<con tent> content##s; \
public: \
name(); \
int Num##content() { return content##s.size (); } \
}

...
DECLARE_CLASS(S core,Staff);

But trust me, you're just letting your bad implementation approach linger
longer, and that's a BAD IDEA(tm).

V
Sep 7 '05 #3

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:R6******** **********@news read1.mlpsca01. us.to.verio.net ...
Jon Slaughter wrote:
I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with
virtually the exact same coding going on.

e.g.

class A
{
std::vector<B*> Bs;
public:
A() { blah; }

void SomeFunc_A() {blah blah blah};
}

class A
Do you mean

class B


ofcourse. (I swear I changed that to a B)
?
{
std::vector<C*> Cs;
public:
B() { blah; }

void SomeFunc_B() {blah blah blah};
}
Without knowing what 'blah blah blah' is in each case, it's rather hard to
make any good suggestions, however, it seems that both classes could be
made into one template (given that 'blah blah blah's are very similar).


as I said, the code in the classes are exact except for naming conventions.

and eventually one of the classes is a "terminal" in the sense it does
not continue the same abstract recursive process.
Abstract recursive process? What are you talking about? There is nothing
abstract or recursive in the two classes presented.


um... do you know what recursion is? If I have one "meta" template like
structure I could use it to generate a whole recursive set of objects.
Abstact means to generalize. If I had the abstract structure that those two
classes are concrete implementations of then to generate class B would be a
recursive process.
My question is, is there any
way to automate this process?


Absolutely. Code generators are common as part of 4GL, IIRC.


Well, I'm not looking to stray to far from the C++ standard. Just enough to
do what I need.
It seems I cannot use templates because I
cannot generate the proper method names are derived from the name of the
class?
Why do you think that the names have to be different?


Huh? Because I said so? because thats how I will program it.
i.e., I can't do something like

Metaclass template <class name, class subname>
class name
{
std::vector<sub name *> subname's';
public:
name() {blah}

void SomeFunc_@'name ' () { blah blah blah}
}

where say the 's' is appended to the subname literal and the @ appends
the string to the someFunc literal...

then I could do something like

Metaclass<A, B> and it produces the class Agiving above and
Metaclass<B,C> would produce B.
It can be done with macros. But I honestly do *not* see why it would be
necessary.


Um, just because you can't see it doesn't mean its not there.
The reason I do this is because right now I have 7 files in my project
that all are virtually exactly the same as just 1(and how I got them was
basicaly using find and replace 3 times to turn the class into a "new"
one that is virtually identical with the other(excep ofcourse the coding
is actualy the same with different literals)).


So, you want to refactor. That's good. Don't stop at automating the task
of naming your classes. If you really have a generic solution, make it
into a template and make sure you use it properly.


I suppose it is refactoring but I want to generate one class and refactor it
into another and another and another and
My question is, is there any way in C++ to do something like this(I know
my code is not valid C++ code above but just giving some example). I
just need to generate a class from a meta class that also can change the
method's names that will be based on the name of the class.
Yes. Use preprocessor macros. Or don't.


Ok, I will look into them.. I guess I don't know the power of the
preprocessor
Actually I will give a more concrete example that I actually kinda use in
my program:

class Score : public Base
{
public:
std::vector<Sta ff> Staffs;
Why is this suddenly public?


Because I knew someone would bitch if I made it private and tried to access
it... I Didn't want to write a member function and overload operator and a
bunch of other shit just get a basic concept across that has nothing to do
with if its private or not.
int NumStaffs() { return (int)Staffs.siz e(); }


Why can't this function be named 'count'? If 'Score' always keeps the
count of 'Staff', IOW, if 'Score' is a collection of 'Staff', then there
is no misinterpretati on.


You are right and maybe I should/will do that if it would be the only way.
I could generalize the class completely so that no information about the
structure I am trying to represent is in the class.

I'd personally rather see NumStaffs than count.

if I do Scores.count() I might think of it as the number of scores and not
the number of staffs(and even though this might be a trival excuse once I
have several nestings it will start to get confusing for no reason except
complete generality).
}

class Staff : public Base
{
public:
std::vector<Bar > Bars;
int NumBars() { return (int)Bars.size( ); }


And this function?... Name it 'count' and you're on your way to making
your classes generic.


um, but whats the point? if I make it so generic then I loose concreteness
and the simplicity of how it models the application. Why not just call all
my objects object1, object2, object3, etc...? thats pretty general? theres
a point when generality makes things worse.
}

class Bar : public Base
{
private:
public:
}

class Base
{
public:
std::vector<Pro perty> Properties;
int NumProperties() { return (int)Properties .size(); }
Again...


again what? are you saying you really need me to make Properties private and
add a public operator [] so I can easily access them just so you are not
confused?
}

class Property
{
private:
public:
}

and I would want to access methods like:

Score.NumStaffs ();
Score.Staffs[0].NumBars();


So, you're going to give the _implementation _detail_ *public* access
specifier? That's not good.


um, why not? it makes perfect sense and models the my problem perfectly
well.

Score.Staffs[0].NumBars(); makes perfect sense compared to

object.object[0].count();
etc...

I know I could make some general template where all methods across the
different classes would have the same name so I might have

Score.NumObject s(); which would return the number of objects in in the
vector in that object and(Staffs in this cass)
Score.Objects[0].NumObjects(); would return same as above but for the
Bars.


But that's bad. You shouldn't access the 'Objects' collection directly.


who said I did, it was an example.. no one said this was my real code I use.
I'm not going to post my real code because first off I don't need to to get
my point across. Wether I access it like I do or not has nothing to do with
my problem or its solution. If you don't like it as a programming pratice
then tuff... I don't access it like that in my code anyways but I see no
need to add extra code to that class just to satisfy you when it doesn't
pertain to the real issue at hand.
The problem with this is I only need the recursiveness
There is no *recursiveness* here. There is only _nestedness_.


um, SAME THING! "nestedness " is a recursive process.
for about 5 classes
and that I want the naming to follow the modelling I'm using(modeling of
Score->Staff->Bar->Notes of music) else it might be confusing to remeber

Score.Objects[0].Objects[3].NumObjects(); is refering to
Yes, that _is_ confusing. Why do you think you'd need that? I would
only think that you might pass


I never said I needed that. That is what I'm trying to avoid. I don't want a
generic class but a template that can create those specific classes who
differ only by the names of the methods, class name and variable names but
the "abstract" code is the same.


Score.Object[i]

into some function where you'd use

MyObject.Object[j]

which in the context won't be confusing and will be absolutely clear
*what* it refers to.
OMG, shut up with this generic crap. You don't know what I'm even trying to
program so how can you know if it will end up confusing or not?

So thats the idea... as you can see most the classes are exactly the same
except for the naming of functions. I do see a problem now with my
example above about just adding 's' to the end... I wouldn't want
Propertys but Properties so there would have to be a way of creating
logical english literal names(i.e., replace ending y with ies when adding
s), etc...

Anything that can do something like this out there? (would save me a lot
of work of having to to mess with 7 files that are identical except for
naming and potential other problems)
Something like

#define DECLARE_CLASS(n ame,content) class name { \
std::vector<con tent> content##s; \
public: \
name(); \
int Num##content() { return content##s.size (); } \
}

...
DECLARE_CLASS(S core,Staff);


Ok, this is basicaly exactly what I need(I didn't know about the token
pasting operator). Ofcourse I would like to do a little more such as turn
'ys' into 'ies' to be consistent(not that it ultimately matters but.
But trust me, you're just letting your bad implementation approach linger
longer, and that's a BAD IDEA(tm).
Tell me one good reason why its bad and I'll tell you 5 why its not. For my
implementation it simplifies the whole process and makes things intuitive
and natural(since they will model the problem very well). I could go ahead
and just start calling object objectnnn and every variable varnnnn and every
method methodnnn just to be general but thats a BAD IDEA(tm).

I don't know why you are making things 1000x more complicated than they need
to be. If your just trying to make me jump through all these hoops because
you think I should generalize the process then you should just say so.

The fact is that when I started the project I didn't realize that 5 out of 7
of my classes were exactly the same except for the naming convention I
didn't know I was going to get into this thing about generalizing. It
actually might actually be easier to just use a generalized class but I
haven't though about it enough to really say... actually I did think about
it(as I mentioned I could do that) but I decided against it because I'd
prefer NumStaffs() to count() (because there is no doubt to the first). I
just don't know if the generalized class would cause more problems than it
solves.

V


Jon
Sep 7 '05 #4

"Dave Rahardja" <as*@me.com> wrote in message
news:iv******** *************** *********@4ax.c om...
On Wed, 7 Sep 2005 02:46:09 -0500, "Jon Slaughter"
<Jo***********@ Hotmail.com>
wrote:
I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with virtually
the exact same coding going on.


Take a look at the ## preprocessor operator.

-dr


Thanks, I didn't know about this but now I do ;)

Jon
Sep 7 '05 #5
Jon Slaughter wrote:
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:R6******** **********@news read1.mlpsca01. us.to.verio.net ...
Jon Slaughter wrote:
I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with
virtually the exact same coding going on.
[...]


I find your replies insulting and your tone contemptuous. If you do
not like (or do not understand) my suggestions feel free not to comment
on them.
Sep 7 '05 #6

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:ab******** ***********@new sread1.mlpsca01 .us.to.verio.ne t...
Jon Slaughter wrote:
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:R6******** **********@news read1.mlpsca01. us.to.verio.net ...
Jon Slaughter wrote:

I have a class that is basicaly duplicated throughout several files with
only members names changing according to the class name yet with
virtually the exact same coding going on.
[...]


I find your replies insulting and your tone contemptuous. If you do
not like (or do not understand) my suggestions feel free not to comment
on them.


fair enough. But I was only trying to return the favor.
Sep 7 '05 #7
In message <11************ *@corp.supernew s.com>, Jon Slaughter
<Jo***********@ Hotmail.com> writes

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:R6******* ***********@new sread1.mlpsca01 .us.to.verio.ne t...
Jon Slaughter wrote:
[big snip]
> It seems I cannot use templates because I
cannot generate the proper method names are derived from the name of the
class?


Why do you think that the names have to be different?


Huh? Because I said so? because thats how I will program it.


[...]
class Staff : public Base
{
public:
std::vector<Bar > Bars;
int NumBars() { return (int)Bars.size( ); }


And this function?... Name it 'count' and you're on your way to making
your classes generic.


um, but whats the point? if I make it so generic then I loose concreteness
and the simplicity of how it models the application. Why not just call all
my objects object1, object2, object3, etc...? thats pretty general? theres
a point when generality makes things worse.


That's not generic, it's merely arbitrary.

The point of giving a function the same meaningful-but-generic name in
all your classes is that you can then apply a templated algorithm to all
of them without having to worry about which class you're dealing with.

Most of your classes appear to model collections of objects at the next
level of the hierarchy. Abstracting the concept of _collection_ allows
you to do many things with them without bothering about the details of
what is inside the container. In my book that's a big *gain* in
simplicity.
--
Richard Herring
Sep 7 '05 #8

"Richard Herring" <ju**@[127.0.0.1]> wrote in message
news:Sm******** ******@baesyste ms.com...
In message <11************ *@corp.supernew s.com>, Jon Slaughter
<Jo***********@ Hotmail.com> writes

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:R6****** ************@ne wsread1.mlpsca0 1.us.to.verio.n et...
Jon Slaughter wrote:
[big snip]

> It seems I cannot use templates because I
cannot generate the proper method names are derived from the name of
the
class?

Why do you think that the names have to be different?
Huh? Because I said so? because thats how I will program it.


[...]
class Staff : public Base
{
public:
std::vector<Bar > Bars;
int NumBars() { return (int)Bars.size( ); }

And this function?... Name it 'count' and you're on your way to making
your classes generic.


um, but whats the point? if I make it so generic then I loose concreteness
and the simplicity of how it models the application. Why not just call
all
my objects object1, object2, object3, etc...? thats pretty general?
theres
a point when generality makes things worse.


That's not generic, it's merely arbitrary.


Well, I suppose. But I think in the context those are generic names(an
arbitrary name would be more like a random name in my book).

The point of giving a function the same meaningful-but-generic name in all
your classes is that you can then apply a templated algorithm to all of
them without having to worry about which class you're dealing with.

I agree and I tried the generic aproach. while it does simplfy the program a
great deal I still get to a point where I cannot go any farther.

Most of your classes appear to model collections of objects at the next
level of the hierarchy. Abstracting the concept of _collection_ allows you
to do many things with them without bothering about the details of what is
inside the container. In my book that's a big *gain* in simplicity.

I do see your pointer, I was able to do a great deal of simplification by
making it generic and maybe in the long run it is better. Though I'm still
not sure original way is bad as far as using the implementation of the
containers its just bad for managing them(Because one has to manage the
exact same code in several different places when its much easier to manage
just one).

--
Richard Herring

Ok, by using a generic template I run into a huge problem that I don't see
how to fix with my limited knownlege of advanced C++ meta programming. By
fix I mean this: By using a generic template I was able to reduce the
multiplician of my code by a factor of 5 down to 2 but it seems because of
my design I cannot reduce it any farther. The follow code demonstrates the
problem(Note it is not exact and not perfect code I'm only typing enough to
demonstrate the problem and nothing else):

Actually here is the generic template that I just created for my problem
minus all the extraneous code that doesn't relate to the problem directly.

#include <vector>
template <class content>
class RDES
{
private:
std::vector<con tent *> _content;
public:
RDES(void) { };

RDES(RDES &o)
{
// Make a deep copy of the content
for(int index = 0; index < o.Count(); index++)
{
Add(*(new content(o[index])));
};
}
int Count() { return (int)_content.s ize(); }

void Add(content &content) { _content.push_b ack(&content); }

void Remove(int index)
{
delete &(*this)[index];
_content.erase( _content.begin( ) + index);
}

void Remove() { Remove(Count()-1); }

content& operator[](int index) { return *(_content[index]); }

virtual ~RDES(void)
{
for(int index = 0; index < Count(); index++)
{
Remove();
}
}

} // class RDES

Now, the problem is that I need make a container that is exactly the same as
this container but inherents itself.

i.e.

template <class content>
class RDES : public Properties
.......

But properties is exactly the same class as RDES without inheriting itself.
i.e.

template <class content>
class Properties
.......

where (.... is exactly the same code with RDES replaced by Properties(only
thing removed as the ': public Properties').
ofcourse you can't do this. Why do I need to do it? because the base class
will be a container of properties(the content will be properties for my
model) and the class itself is a container of some other objects(i.e. the
basic will contain properties for those objects).

The issue ofcourse is that the method names from the base class are exactly
the same of the class itself and hence there is no way to distingish from
the bass and the class methods.

So you might say why not just make something like

template <class content>
class RDES
{
private:
std::vector<con tent *> _content;
std::vector<Pro perty *> _properties;

......

and the thing is that all the code will be duplicated still(so I'm back to
the original problem of having code that is duplicated)
Also Property is itself a RDES class that doesn't inherit Properties.

I could do something like

template <class content>
class RDES
{
private:
std::vector<con tent *> _content;
public:
RDES Properties;
.....
and then I can access the properties class through an extra field access (so
if I wanted to get to the Add method for the properties I would have to do
someClass.Prope rties.Add() but I'd prefer someClass.Add() (but ofcourse this
confuses the problem with the child class's Add()... this is the whole
reason why I wanted some type of automatic naming so I Could do
someClass.AddPr operties() and someClass.Add() instead of
someClass.Prope rties.Add()... )

So while using this will solve the problem of the scope it adds and extra
field access I end up getting an infintely nested class because Properties
will contain properties will contain properties and so on.

So what it boils down to I have to have two RDES classes one that inherits
the other(or uses the the extra Properties variable as above)
I.E.

template <class content>
class RDES
{
private:
std::vector<con tent *> _content;
public:
RDES2<Property> Properties;
RDES(void) { };

RDES(RDES &o)
{
// Make a deep copy of the content
for(int index = 0; index < o.Count(); index++)
{
Add(*(new content(o[index])));
};
}
int Count() { return (int)_content.s ize(); }

void Add(content &content) { _content.push_b ack(&content); }

void Remove(int index)
{
delete &(*this)[index];
_content.erase( _content.begin( ) + index);
}

void Remove() { Remove(Count()-1); }

content& operator[](int index) { return *(_content[index]); }

virtual ~RDES(void)
{
for(int index = 0; index < Count(); index++)
{
Remove();
}
}

} // class RDES

--------------------------------------------

template <class content>
class RDES2
{
private:
std::vector<con tent *> _content;
public:
RDES2(void) { };

RDES2(RDES &o)
{
// Make a deep copy of the content
for(int index = 0; index < o.Count(); index++)
{
Add(*(new content(o[index])));
};
}
int Count() { return (int)_content.s ize(); }

void Add(content &content) { _content.push_b ack(&content); }

void Remove(int index)
{
delete &(*this)[index];
_content.erase( _content.begin( ) + index);
}

void Remove() { Remove(Count()-1); }

content& operator[](int index) { return *(_content[index]); }

virtual ~RDES2(void)
{
for(int index = 0; index < Count(); index++)
{
Remove();
}
}

} // class RDES2

Notice the only thign different between RDES2 and RDES is "RDES2<Property >
Properties;" Property is a terminal of the recursion(it is a simply a non
RDES class (but it really doesn't matter.. just pointing out that eventually
the recursion ends).

So as you can see I can solve this problem by having two templates but they
are exactly the same except for one minor(well its major) difference. I'm
back were I started because I still have to manage 2 classes(I had to manage
5 before but I can automatic it by writing a small find and replace util
that fixes everything up).
So what I'll probably do is just write program to find and replace what I
need and call it in a bat file to duplicate the files and fix what needs to
be fixed. I've been doing this manually for the last couple of days and was
just seeing if there was a much more general method available. While I do
like the idea of being general I'm not so sure it works out the best in this
situation... though maybe you guys know how to fix the above problem
(basicaly have some conditional template class) then I might go with it.

i.e. if something like this is possible

template <class content>
class RDES
{
private:
std::vector<con tent *> _content;
public:
#ifdef __RDESPropertie s
RDES2 Properties;
#endif
.....
then then I do something like

#undef __RDESPropertie s
typedef RDES<Properties > RDES2

#define __RDESPropertie s
typedef RDES<Note > Beat; // Note is a terminal of this process
typedef RDES<Beat > Bar;
typedef RDES<Bar > Staff;
typedef RDES<Staff > Score;
Thisway I get my higherarchy with the properties included. Only drawback is
that I have to access my properties as something like Score.Propertie s but
it isn't that big a deal.

This way I get one generic class that needs to be updated... but problem is
it doesn't work ;/

Any help would be appreciated

Thanks,
Jon

p.s. sorry if I'm being confusing but I'm doing the best I can to explain
the situation.


Sep 8 '05 #9
the code I'm trying to get to work is

template <class content, bool t = true>
class RDES
{
private:
std::vector<con tent *> _content;
public:
#if t
RDES2 Properties;
#endif

.....
}
typedef RDES<end, false > RDES2;

typedef RDES<end, true > Score;

but the Score class doesn't get the Properties object(the condition
compilation Properties is not included in Score. :/)

What I was hoping was that RDES2 would be created as a new template that had
the didn't have the Properties object and the Score would include it. This
doesn't work though as when I try to access Properties from a Score object
it says its not a member of RDES<content, t>.
Maybe it is possible this way but I'm not using typedef correctly. Going to
try to read up on preprocessing.
Jon
Sep 8 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
8683
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9170
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8904
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8876
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6531
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5867
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4372
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2341
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.