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

Meta class programming question

P: n/a
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<subname *> 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<Staff> Staffs;
int NumStaffs() { return (int)Staffs.size(); }
}

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<Property> 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.NumObjects(); 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
Share this Question
Share on Google+
21 Replies


P: n/a
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

P: n/a
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<subname *> 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<Staff> Staffs;
Why is this suddenly public?
int NumStaffs() { return (int)Staffs.size(); }
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 misinterpretation.
}

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<Property> 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.NumObjects(); 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(name,content) class name { \
std::vector<content> content##s; \
public: \
name(); \
int Num##content() { return content##s.size(); } \
}

...
DECLARE_CLASS(Score,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

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:R6******************@newsread1.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<subname *> 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<Staff> 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.size(); }


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 misinterpretation.


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<Property> 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.NumObjects(); 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(name,content) class name { \
std::vector<content> content##s; \
public: \
name(); \
int Num##content() { return content##s.size(); } \
}

...
DECLARE_CLASS(Score,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

P: n/a

"Dave Rahardja" <as*@me.com> wrote in message
news:iv********************************@4ax.com...
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

P: n/a
Jon Slaughter wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:R6******************@newsread1.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

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ab*******************@newsread1.mlpsca01.us.t o.verio.net...
Jon Slaughter wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:R6******************@newsread1.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

P: n/a
In message <11*************@corp.supernews.com>, Jon Slaughter
<Jo***********@Hotmail.com> writes

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:R6******************@newsread1.mlpsca01.us.t o.verio.net...
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

P: n/a

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

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:R6******************@newsread1.mlpsca01.us. to.verio.net...
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<content *> _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.size(); }

void Add(content &content) { _content.push_back(&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<content *> _content;
std::vector<Property *> _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<content *> _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.Properties.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.AddProperties() and someClass.Add() instead of
someClass.Properties.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<content *> _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.size(); }

void Add(content &content) { _content.push_back(&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<content *> _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.size(); }

void Add(content &content) { _content.push_back(&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<content *> _content;
public:
#ifdef __RDESProperties
RDES2 Properties;
#endif
.....
then then I do something like

#undef __RDESProperties
typedef RDES<Properties> RDES2

#define __RDESProperties
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.Properties 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

P: n/a
the code I'm trying to get to work is

template <class content, bool t = true>
class RDES
{
private:
std::vector<content *> _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

P: n/a

Jon Slaughter wrote:
the code I'm trying to get to work is

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


That doesn't do what you think (or hope) it does. The preprocessor
does not understand templates. You're hoping that the above three
lines will be prepocessed into "RDES2 Properties" if t is true and into
nothing if t is false. But in reality, the preprocessor has no clue
that t is a template parameter and rather simply sees the t as an
undefined identifier, which it replaces with 0. Thus, the #if
expression always evaluates to false, so RDES2 Properties line is never
included by the preprocessor. Only AFTER the proprocessor is finished
does the compiler parse your template.

Best regards,

Tom

Sep 8 '05 #11

P: n/a

"Thomas Tutone" <Th***********@yahoo.com> wrote in message
news:11*********************@g49g2000cwa.googlegro ups.com...

Jon Slaughter wrote:
the code I'm trying to get to work is

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


That doesn't do what you think (or hope) it does. The preprocessor
does not understand templates. You're hoping that the above three
lines will be prepocessed into "RDES2 Properties" if t is true and into
nothing if t is false. But in reality, the preprocessor has no clue
that t is a template parameter and rather simply sees the t as an
undefined identifier, which it replaces with 0. Thus, the #if
expression always evaluates to false, so RDES2 Properties line is never
included by the preprocessor. Only AFTER the proprocessor is finished
does the compiler parse your template.

Best regards,

Tom


yeah, I see. The preprocessor will parse the file first and do its thing and
sence the template is not part of the preprocessor the #if statement just
gets removed from it. Ofcourse I think even if it did work I'd still get
the error about using a class inside its definition.

So my question is: Is there any way to use a class inside itself? Maybe a
pointer but I'd be wasting a pointer in those cases where I don't use the
class(as when the class itself is representing a properties class).
Best way I can put it into words if I'm trying to use one template to
represent two classes that are slightly different. Its sorta polymorphism
that isn't exact or maybe a "dynamic template" or something like that. Maybe
there is some more advanced ways that I'm not awear of to do this sorta
thing(after all, I'm kinda flying by the seat of my pants at the moment and
if I could just get pointed in the right direction then I might be able to
get a grip on it)?

Thanks,

Jon
Sep 8 '05 #12

P: n/a
Jon Slaughter wrote:
So my question is: Is there any way to use a class inside itself? Maybe a
pointer but I'd be wasting a pointer in those cases where I don't use the
class(as when the class itself is representing a properties class).
Best way I can put it into words if I'm trying to use one template to
represent two classes that are slightly different. Its sorta polymorphism
that isn't exact or maybe a "dynamic template" or something like that. Maybe
there is some more advanced ways that I'm not awear of to do this sorta
thing(after all, I'm kinda flying by the seat of my pants at the moment and
if I could just get pointed in the right direction then I might be able to
get a grip on it)?


You will need to forward declare the class and use pointers, you can't
have a class as a direct member of itself, because the size cannot be
determined (it's recursive).

Have you thought about having something like the adaptor pattern against
a common implementation:

/* Common Implementation */
class MyClassImpl {
public:
void SomeFunc() {
// foo
}
};

/* Adaption 1 */
class MyClass1 {
MyClassImpl impl_;
public:
inline void SomeFunc_MyClass1() {
impl_.SomeFunc();
}
};

/* Adaption 2 */
class MyClass2 {
MyClassImpl impl_;
public:
inline void SomeFunc_MyClass2() {
impl_.SomeFunc();
}
};

So that you only have to maintain a very thin interface, not the
implementation?

You could also use inheritance, but in that case, probably MyClassImpl
will be abstract, and you'd probably want to inherit privately (or
protected).

Ben
--
I'm not just a number. To many, I'm known as a String...
Sep 8 '05 #13

P: n/a

"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126171026.d07cac1e0dd2a95b08c5ce3e65cb3fcf@t eranews...
Jon Slaughter wrote:
So my question is: Is there any way to use a class inside itself? Maybe a
pointer but I'd be wasting a pointer in those cases where I don't use the
class(as when the class itself is representing a properties class).
Best way I can put it into words if I'm trying to use one template to
represent two classes that are slightly different. Its sorta
polymorphism that isn't exact or maybe a "dynamic template" or something
like that. Maybe there is some more advanced ways that I'm not awear of
to do this sorta thing(after all, I'm kinda flying by the seat of my
pants at the moment and if I could just get pointed in the right
direction then I might be able to get a grip on it)?
You will need to forward declare the class and use pointers, you can't
have a class as a direct member of itself, because the size cannot be
determined (it's recursive).


Yes, but if I could someone create a template of the first one that is not
recursive and use that one in the recursive one then it wouldn't really be
recursive any more(well at most 1 lvl deep). Thats what I was trying to do
before but it didn't work out. I mean, basicaly the size can be determined
if its recusive but th the recursion has some finite end.. I think the
problem, atleast it seems, is that C++ doesn't have a way to know when to
stop the recursion. if I could do something like

class X
{
public:
X@3 Properties;
}

where the compiler would interpret @3 only accept 3 lvls deep and when it
gets to the 4 it removes that declaration then the recursion would end. I
suppose the problem with something like that is it just creates more
problems ;)

Have you thought about having something like the adaptor pattern against
a common implementation:

/* Common Implementation */
class MyClassImpl {
public:
void SomeFunc() {
// foo
}
};

/* Adaption 1 */
class MyClass1 {
MyClassImpl impl_;
public:
inline void SomeFunc_MyClass1() {
impl_.SomeFunc();
}
};

/* Adaption 2 */
class MyClass2 {
MyClassImpl impl_;
public:
inline void SomeFunc_MyClass2() {
impl_.SomeFunc();
}
};

So that you only have to maintain a very thin interface, not the
implementation?
I didn't think about that but it is a possibility. It does simplify the
process a great deal. I'll have to think more about how good an idea that
is. Not sure if it would be any better than just writing a utility to find
and replace the "key area" and duplicate it in a another file.

i.e.

class X
{
public:
X Properties;
}

then just create a simple util that finds "X Properties" and replaces it
with "Y Properties" then duplicates the exact same code in another file but
rename the class Y instead and remove the "X Properties".

So Y wouldn't be recursive but have the exact same methods and members(minus
properties) and then I'd just have to run this utility ever time I make a
major update to X(or have it run before the code is compiled automatically
by the IDE I guess).

You could also use inheritance, but in that case, probably MyClassImpl
will be abstract, and you'd probably want to inherit privately (or
protected).

How? You mean inherit MyClassImpl into the Adaptation classes? I could do
that but since I'm being so general with my method names I'd rather not use
inheritence... though you method can be used with the general names and
would have worked before when I didn't decide to make my template generic
too... its actually a pretty decent method but I think it might be more work
than just making a simple utility that duplicates the class and removes the
"recursion" aspect.

Basicaly I'm trying to completely get away from managing more than 1 class.
While your method does virtually eliminate the problem the utility method
completely eliminates it ;)
Ben
--
I'm not just a number. To many, I'm known as a String...

Thanks for the info though... I might actually use it after I think about
it. I'm not sure how much more my classes will grow and how much they will
end up being changed and even if there is C++ compatiable way to do it with
just one class/template.

Jon
Sep 8 '05 #14

P: n/a
Jon Slaughter wrote:
"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126171026.d07cac1e0dd2a95b08c5ce3e65cb3fcf@t eranews...
You will need to forward declare the class and use pointers, you can't
have a class as a direct member of itself, because the size cannot be
determined (it's recursive).

Yes, but if I could someone create a template of the first one that is not
recursive and use that one in the recursive one then it wouldn't really be
recursive any more(well at most 1 lvl deep). Thats what I was trying to do
before but it didn't work out. I mean, basicaly the size can be determined
if its recusive but th the recursion has some finite end.. I think the
problem, atleast it seems, is that C++ doesn't have a way to know when to
stop the recursion. if I could do something like

class X
{
public:
X@3 Properties;
}

where the compiler would interpret @3 only accept 3 lvls deep and when it
gets to the 4 it removes that declaration then the recursion would end. I
suppose the problem with something like that is it just creates more
problems ;)


Ahh yes, but the compiler is unlikely to be able to do that.

I'm not sure where it would get you, but you could probably do something
like:

template<int I>
class MyClass{
private:
MyClass<I-1>* child_;
}

And start off with:

MyClass<4> root;

But I'm not sure how you would terminate when I-1 = 0.
You could also use inheritance, but in that case, probably MyClassImpl
will be abstract, and you'd probably want to inherit privately (or
protected).

How? You mean inherit MyClassImpl into the Adaptation classes? I could do
that but since I'm being so general with my method names I'd rather not use
inheritence...


Yes:

/* Common Abstract Implementation */
class MyClassImpl {
public:
void SomeFunc() {
// foo
}
virtual ~MyClassImpl() = 0;
};

/* Adaption 1 */
class MyClass1 : MyClassImpl {
public:
inline void SomeFunc_MyClass1() {
MyClassImpl::SomeFunc();
}
};

With private or protected inheritance you're inheriting the
implementation the method names are irrelevant, in fact, thats the sole
purpose of using the wrapper... to just change the method names.
though you method can be used with the general names and
would have worked before when I didn't decide to make my template generic
too... its actually a pretty decent method but I think it might be more work
than just making a simple utility that duplicates the class and removes the
"recursion" aspect.
I'm not so sure... I suspect the utility will take a lot longer than you
expect it will, by the time it's debugged and working.
Basicaly I'm trying to completely get away from managing more than 1 class.
While your method does virtually eliminate the problem the utility method
completely eliminates it ;)
Well, personally I think it just shifts the problem from writing the
code to writing the utility.
Thanks for the info though... I might actually use it after I think about
it. I'm not sure how much more my classes will grow and how much they will
end up being changed and even if there is C++ compatiable way to do it with
just one class/template.


If you want to have the different names you'll have to maintain them
yourself, it's the simplest C++ way I can think of. By the time you
write a utility and test it and faff around when it doesn't work, and
then decide that actually there is a difference between your classes and
try to work that into your utility... You might as well have just
written the wrappers. They are so simple that there should be no
overhead in space or time for the code.

Ben
--
I'm not just a number. To many, I'm known as a String...
Sep 8 '05 #15

P: n/a
Ben Pope wrote:
Jon Slaughter wrote:
"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126171026.d07cac1e0dd2a95b08c5ce3e65cb3fcf@t eranews...
You will need to forward declare the class and use pointers, you
can't
have a class as a direct member of itself, because the size cannot
be determined (it's recursive).

Yes, but if I could someone create a template of the first one that
is not recursive and use that one in the recursive one then it
wouldn't really be recursive any more(well at most 1 lvl deep).
Thats what I was trying to do before but it didn't work out. I mean,
basicaly the size can be determined if its recusive but th the
recursion has some finite end.. I think the problem, atleast it
seems, is that C++ doesn't have a way to know when to stop the
recursion. if I could do something like

class X
{
public:
X@3 Properties;
}

where the compiler would interpret @3 only accept 3 lvls deep and
when it gets to the 4 it removes that declaration then the recursion
would end. I suppose the problem with something like that is it
just creates more problems ;)


Ahh yes, but the compiler is unlikely to be able to do that.

I'm not sure where it would get you, but you could probably do
something like:

template<int I>
class MyClass{
private:
MyClass<I-1>* child_;
}

And start off with:

MyClass<4> root;

But I'm not sure how you would terminate when I-1 = 0.


You would specialise the template for the case 'I equals 0'; this will
terminate the recursion.
template<>
class MyClass<0>{
};

The MyClass<4> type would then look like this:

MyClass<4> {
MyClass<3>* child_;
};

MyClass<3> {
MyClass<2>* child_;
};

MyClass<2> {
MyClass<1>* child_;
};

MyClass<1> {
MyClass<0>* child_; // No more kids after this one
};
You could also use inheritance, but in that case, probably
MyClassImpl
will be abstract, and you'd probably want to inherit privately (or
protected).

How? You mean inherit MyClassImpl into the Adaptation classes? I
could do that but since I'm being so general with my method names
I'd rather not use inheritence...


Yes:

/* Common Abstract Implementation */
class MyClassImpl {
public:
void SomeFunc() {
// foo
}
virtual ~MyClassImpl() = 0;
};

/* Adaption 1 */
class MyClass1 : MyClassImpl {
public:
inline void SomeFunc_MyClass1() {
MyClassImpl::SomeFunc();
}
};

With private or protected inheritance you're inheriting the
implementation the method names are irrelevant, in fact, thats the
sole purpose of using the wrapper... to just change the method names.
> though you method can be used with the general names and
would have worked before when I didn't decide to make my template
generic too... its actually a pretty decent method but I think it
might be more work than just making a simple utility that duplicates
the class and removes the "recursion" aspect.


I'm not so sure... I suspect the utility will take a lot longer than
you expect it will, by the time it's debugged and working.
Basicaly I'm trying to completely get away from managing more than 1
class. While your method does virtually eliminate the problem the
utility method completely eliminates it ;)


Well, personally I think it just shifts the problem from writing the
code to writing the utility.
Thanks for the info though... I might actually use it after I think
about it. I'm not sure how much more my classes will grow and how
much they will end up being changed and even if there is C++
compatiable way to do it with just one class/template.


If you want to have the different names you'll have to maintain them
yourself, it's the simplest C++ way I can think of. By the time you
write a utility and test it and faff around when it doesn't work, and
then decide that actually there is a difference between your classes
and
try to work that into your utility... You might as well have just
written the wrappers. They are so simple that there should be no
overhead in space or time for the code.

Ben

Sep 10 '05 #16

P: n/a

"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126182709.89ac7e9493069b87dcef75fdf0723810@t eranews...
Jon Slaughter wrote:
"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126171026.d07cac1e0dd2a95b08c5ce3e65cb3fcf@t eranews...
<snip>

well I basicaly just made a generic class as several have said to do and
made a utility to duplicate the class and add some deep copy code to the
copy constructor. The utility only took about 30 mins to do and setup in my
build project. Its just a hack but it will allow me to only have to worry
about 1 class(ofcourse it only looks for tokens and modifies them and so if
the syntax is wrong or it can screw everything up. But in this case not much
has to be changed that requires any syntatic analysis).
Going to look at that recursive procedure you mentioned with Tim's advice
too. Seems like C++ can handle what I need ;) I'll check it out and report
on how it turns out.

Ben
--
I'm not just a number. To many, I'm known as a String...


Thanks
Jon
Sep 11 '05 #17

P: n/a

"Tim Clacy" <no*******@nospamphaseone.nospamdk> wrote in message
news:43***********************@dread12.news.tele.d k...
Ben Pope wrote:
Jon Slaughter wrote:
"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126171026.d07cac1e0dd2a95b08c5ce3e65cb3fcf@t eranews...

You will need to forward declare the class and use pointers, you
can't
have a class as a direct member of itself, because the size cannot
be determined (it's recursive).
Yes, but if I could someone create a template of the first one that
is not recursive and use that one in the recursive one then it
wouldn't really be recursive any more(well at most 1 lvl deep).
Thats what I was trying to do before but it didn't work out. I mean,
basicaly the size can be determined if its recusive but th the
recursion has some finite end.. I think the problem, atleast it
seems, is that C++ doesn't have a way to know when to stop the
recursion. if I could do something like

class X
{
public:
X@3 Properties;
}

where the compiler would interpret @3 only accept 3 lvls deep and
when it gets to the 4 it removes that declaration then the recursion
would end. I suppose the problem with something like that is it
just creates more problems ;)


Ahh yes, but the compiler is unlikely to be able to do that.

I'm not sure where it would get you, but you could probably do
something like:

template<int I>
class MyClass{
private:
MyClass<I-1>* child_;
}

And start off with:

MyClass<4> root;

But I'm not sure how you would terminate when I-1 = 0.


You would specialise the template for the case 'I equals 0'; this will
terminate the recursion.
template<>
class MyClass<0>{
};

The MyClass<4> type would then look like this:

MyClass<4> {
MyClass<3>* child_;
};

MyClass<3> {
MyClass<2>* child_;
};

MyClass<2> {
MyClass<1>* child_;
};

MyClass<1> {
MyClass<0>* child_; // No more kids after this one
};


AWESOME!!! Almost exactly what I need! it does the job almost perfectly but
one complaint is that the terminal class is still represented... but since
its empty its not that big a deal.

Is there anywhere I can learn more about "advanced" template programming?
This recursive ability seems like a very powerful feature and I never
expected C++ to be able to do it. Surely there are more powerful features
like this?

I'm virtually completely new to the concept of templates and so I just have
a basic grasp of what they do but I can't seem to find any good information
online about them. Documentation isn't what it used to be and it seems like
I just end up going around in circles trying to find something specific but
never get it.

Is there any book worth that goes into a good deal of depth on the
"advanced" features of C++. (I'm not saying that the above is advanced but
that it not something that I would have ordinarily thought possible because,
mainly, I didn't know you could have a "template counter" and specialize
it).

Thanks for the help!! I really appreciate it!

Still might run into some problems but I think I can probably hack it out.

Jon
Sep 11 '05 #18

P: n/a
> Is there anywhere I can learn more about "advanced" template programming?
This recursive ability seems like a very powerful feature and I never
expected C++ to be able to do it. Surely there are more powerful features
like this?


Modern C++ Design, by Andrei Alexandrescu is an awesome book on
programming with templates.

john
Sep 11 '05 #19

P: n/a

"John Harrison" <jo*************@hotmail.com> wrote in message
news:49*****************@newsfe4-gui.ntli.net...
Is there anywhere I can learn more about "advanced" template programming?
This recursive ability seems like a very powerful feature and I never
expected C++ to be able to do it. Surely there are more powerful
features like this?


Modern C++ Design, by Andrei Alexandrescu is an awesome book on
programming with templates.

john


Thanks, I'll check it out.

Jon
Sep 11 '05 #20

P: n/a
Jon Slaughter wrote:
"Tim Clacy" <no*******@nospamphaseone.nospamdk> wrote in message
news:43***********************@dread12.news.tele.d k...
Ben Pope wrote:
Jon Slaughter wrote:
"Ben Pope" <benpope81@_pants_gmail.com> wrote in message
news:1126171026.d07cac1e0dd2a95b08c5ce3e65cb3fcf@t eranews...

> You will need to forward declare the class and use pointers, you
> can't
> have a class as a direct member of itself, because the size cannot
> be determined (it's recursive).
Yes, but if I could someone create a template of the first one that
is not recursive and use that one in the recursive one then it
wouldn't really be recursive any more(well at most 1 lvl deep).
Thats what I was trying to do before but it didn't work out. I
mean, basicaly the size can be determined if its recusive but th
the recursion has some finite end.. I think the problem, atleast it
seems, is that C++ doesn't have a way to know when to stop the
recursion. if I could do something like

class X
{
public:
X@3 Properties;
}

where the compiler would interpret @3 only accept 3 lvls deep and
when it gets to the 4 it removes that declaration then the
recursion would end. I suppose the problem with something like
that is it
just creates more problems ;)

Ahh yes, but the compiler is unlikely to be able to do that.

I'm not sure where it would get you, but you could probably do
something like:

template<int I>
class MyClass{
private:
MyClass<I-1>* child_;
}

And start off with:

MyClass<4> root;

But I'm not sure how you would terminate when I-1 = 0.

You would specialise the template for the case 'I equals 0'; this
will terminate the recursion.
template<>
class MyClass<0>{
};

The MyClass<4> type would then look like this:

MyClass<4> {
MyClass<3>* child_;
};

MyClass<3> {
MyClass<2>* child_;
};

MyClass<2> {
MyClass<1>* child_;
};

MyClass<1> {
MyClass<0>* child_; // No more kids after this one
};


AWESOME!!! Almost exactly what I need! it does the job almost
perfectly but one complaint is that the terminal class is still
represented... but since its empty its not that big a deal.

Is there anywhere I can learn more about "advanced" template
programming? This recursive ability seems like a very powerful
feature and I never expected C++ to be able to do it. Surely there
are more powerful features like this?


There's quite a bit of material on the Internet (google C++ template
metaprogram)
http://osl.iu.edu/~tveldhui/papers/T.../meta-art.html
I'm virtually completely new to the concept of templates and so I
just have a basic grasp of what they do but I can't seem to find any
good information online about them. Documentation isn't what it used
to be and it seems like I just end up going around in circles trying
to find something specific but never get it.

Is there any book worth that goes into a good deal of depth on the
"advanced" features of C++. (I'm not saying that the above is
advanced but that it not something that I would have ordinarily
thought possible because, mainly, I didn't know you could have a
"template counter" and specialize it).

Thanks for the help!! I really appreciate it!

Still might run into some problems but I think I can probably hack it
out.

Jon

Sep 12 '05 #21

P: n/a
Tim Clacy wrote:
Ben Pope wrote:
But I'm not sure how you would terminate when I-1 = 0.


You would specialise the template for the case 'I equals 0'; this will
terminate the recursion.
template<>
class MyClass<0>{
};


Good work.

Ben
--
I'm not just a number. To many, I'm known as a String...
Sep 12 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.