473,396 Members | 1,714 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Template metaprogramming question

Hi C++ Experts !
I have a little weird requirement.

I have a base class, say B and lots of classes D1 .. Dn publicly
derived from it. Over the course of development the number of derived
classes may increase.
I want that before the execution of one of my particular code, I
should have a list of pointers to all the derived classes, say
std::list<B*ptrList; // contains 'n' elements which are pointers to
D1 .. Dn.

I don't want to have anything like:
ptrList.push_back (new D1);
ptrList.push_back (new D2);
...

Also I don't want to instantiate any static variable of D1 .. Dn, so
that inside the constructor I may register the 'this' pointer.

All I want is the developer should just write the definition of
derived classes, possibly with some constraints and should not bother
about anything else.

Recently I read about 'TypeLists' in Modern C++ design. I was
wondering if I can use it here.

Inside the constructor of the derived classes, I may populate its type
in a 'TypeList'. The 'TypeList' will be full with 'n' elements at the
compile time itself.
Now if I only can do

for each type T in 'TypeList' {
// make sure that type T is derived class of B
// may be through
// assert (dynamic_cast<B*>(T));

ptrList.push_back (new T);
}
my problem will be solved.

Do you guys see any problem with this approach?

Any discussion on this will be appreciated.

Thanks in advance !!
Suman Nandan.
Jul 15 '08 #1
4 1842
su**********@gmail.com wrote:
Hi C++ Experts !
I have a little weird requirement.

I have a base class, say B and lots of classes D1 .. Dn publicly
derived from it. Over the course of development the number of derived
classes may increase.
I want that before the execution of one of my particular code, I
should have a list of pointers to all the derived classes, say
std::list<B*ptrList; // contains 'n' elements which are pointers to
D1 .. Dn.
There are no "pointers to classes", only pointers to objects, and you
understand that, right?

What purpose would such list serve?
I don't want to have anything like:
ptrList.push_back (new D1);
ptrList.push_back (new D2);
..
To have anything like that *where*? What would it do (for you)?
>
Also I don't want to instantiate any static variable of D1 .. Dn, so
that inside the constructor I may register the 'this' pointer.
Inside which constructor? Inside every derived class constructor?
All I want is the developer should just write the definition of
derived classes, possibly with some constraints and should not bother
about anything else.
The simplest solution I can think of to "register" your derived class
with the base class is a special "registrar" object which, when
instantiated passes some data (like its own address or the address of
the containing object) to the base class' registering function. The
details of the process are for you to determine, but this should give
you an idea.
>
Recently I read about 'TypeLists' in Modern C++ design. I was
wondering if I can use it here.
Mmm... I don't think this is something you would be able to use here.
Inside the constructor of the derived classes, I may populate its type
in a 'TypeList'. The 'TypeList' will be full with 'n' elements at the
compile time itself.
Now if I only can do

for each type T in 'TypeList' {
// make sure that type T is derived class of B
// may be through
// assert (dynamic_cast<B*>(T));

ptrList.push_back (new T);
}
my problem will be solved.
What problem is that?
Do you guys see any problem with this approach?
Well, yes. 'Typelist' (or anything like this) is compile-time
information and most likely not going to suit you. I shouldn't have to
update your base class information if I add a derived class in my own
module.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 15 '08 #2
On 15 juil, 14:59, suman.nan...@gmail.com wrote:
Hi C++ Experts !
I have a little weird requirement.

I have a base class, say B and lots of classes D1 .. Dn publicly
derived from it. Over the course of development the number of derived
classes may increase.
I want that before the execution of one of my particular code, I
should have a list of pointers to all the derived classes, say
std::list<B*ptrList; // contains 'n' elements which are pointers to
D1 .. Dn.

I don't want to have anything like:
ptrList.push_back (new D1);
ptrList.push_back (new D2);
..

Also I don't want to instantiate any static variable of D1 .. Dn, so
that inside the constructor I may register the 'this' pointer.

All I want is the developer should just write the definition of
derived classes, possibly with some constraints and should not bother
about anything else.

Recently I read about 'TypeLists' in Modern C++ design. I was
wondering if I can use it here.

Inside the constructor of the derived classes, I may populate its type
in a 'TypeList'. The 'TypeList' will be full with 'n' elements at the
compile time itself.
Now if I only can do

* *for each type T in 'TypeList' *{
* * * // make sure that type T is derived class of B
* * * // may be through
* * * // assert (dynamic_cast<B*>(T));

* * * *ptrList.push_back (new T);
* *}
my problem will be solved.

Do you guys see any problem with this approach?

Any discussion on this will be appreciated.

Thanks in advance !!
Suman Nandan.

If you want to go with this design, here are some very quick
guidelines (sorry I'm in a hurry).

You need :

1) a for_each structure that will iterate through the typelist :
something like (simplified and untested example) :

template < class Typelist >
struct for_each {
static void run ()
{
ptrList.push_back (new Typelist::Head);
for_each< Typelist::Tail >::run();
}
};
template < >
struct for_each< NullType {
static void run () {}
};
2) the is_derived_from idiom :

template< class Base, class Derived >
struct IsDerivedFrom{
typedef char Yes;
struct No { char x[2]; };

static Yes Test( Base* );
static No Test( ... );

enum {check = sizeof( Test( static_cast< Derived* >(0) ) )
== sizeof( Yes )
};
};
3) use the is_derived_from idiom to enhance the for_each structure.

template < class Typelist, class Base, bool IsDerived >
struct for_each_derived {
...
for_each_derived< Typelist::Tail,
Base,
is_derived_from< Base,
Typelist::Tail::Head >
>::run();
...
};

// template specializations on IsDerived = true or false ...
Alexandre Courpron.
Jul 15 '08 #3
su**********@gmail.com wrote:
Hi C++ Experts !
I have a little weird requirement.

I have a base class, say B and lots of classes D1 .. Dn publicly
derived from it. Over the course of development the number of derived
classes may increase.
I want that before the execution of one of my particular code, I
should have a list of pointers to all the derived classes, say
std::list<B*ptrList; // contains 'n' elements which are pointers to
D1 .. Dn.

I don't want to have anything like:
ptrList.push_back (new D1);
ptrList.push_back (new D2);
..
As Bazarov stated, use a registration object.
// id argument is unnecissary for registration, but it does make it
possible to register more than
// one control in a .cpp file while still making some sense.
#define REGISTER(whatever, id) \
namespace \
{ \
ControlCenter::registration reg_##id =
ControlCenter::control_center().register(whatever) ; \
}

In my case, id is an integral defined in resource.h as a Win32 control
object and this implements a state/command pattern tool system.

ControlCenter::registration can easily simply be a bool and is normally
ignored. You'll be able to access it if necessary, keeping scoping
issues in mind, though as the variable name is quite predictable.

Developers write a class and then put "REGISTER(construction, id)" in
the cpp file. You could easily simply use the ID instead, or something
along those lines, so that instantiation is not necessary (in my case it
is). There's no need to even have a header for these objects at
all...the class interface and implementation can be in the CPP file and
never exposed to anyone at all.
>
Also I don't want to instantiate any static variable of D1 .. Dn, so
that inside the constructor I may register the 'this' pointer.
I don't know what you mean here so I can't say if it'll solve your problem.
>
All I want is the developer should just write the definition of
derived classes, possibly with some constraints and should not bother
about anything else.
What you want is not possible, at least no way I can think of. It's not
really a template metaprogramming problem either. There might be
something you could do with a traits function explicit instantiation,
one that the REGISTER macro would create, but I don't understand what
your problem is well enough to say.
Jul 15 '08 #4
On Jul 15, 11:03 pm, Noah Roberts <u...@example.netwrote:
suman.nan...@gmail.com wrote:
I have a base class, say B and lots of classes D1 .. Dn
publicly derived from it. Over the course of development the
number of derived classes may increase.
I want that before the execution of one of my particular
code, I should have a list of pointers to all the derived
classes, say std::list<B*ptrList; // contains 'n' elements
which are pointers to D1 .. Dn.
I don't want to have anything like:
ptrList.push_back (new D1);
ptrList.push_back (new D2);
..
As Bazarov stated, use a registration object.
// id argument is unnecissary for registration, but it does make it
possible to register more than
// one control in a .cpp file while still making some sense.
#define REGISTER(whatever, id) \
namespace \
{ \
ControlCenter::registration reg_##id =
ControlCenter::control_center().register(whatever) ; \
}
Just an idea, but if you use __LINE__ instead of id, and you
won't need the extra argument.
In my case, id is an integral defined in resource.h as a Win32
control object and this implements a state/command pattern
tool system.
ControlCenter::registration can easily simply be a bool and is
normally ignored. You'll be able to access it if necessary,
keeping scoping issues in mind, though as the variable name is
quite predictable.
Developers write a class and then put "REGISTER(construction,
id)" in the cpp file. You could easily simply use the ID
instead, or something along those lines, so that instantiation
is not necessary (in my case it is). There's no need to even
have a header for these objects at all...the class interface
and implementation can be in the CPP file and never exposed to
anyone at all.
I'm not sure I understand. You need a header for the class
ControlCenter (or whatever it would be called), and the register
macro, since the registration will take place in many different
files. (Personally, I've never bothered with the macro. I just
define a member class of ControlCenter, and require a static
instance of that, e.g.:
ControlCenter::Registerer someId( whatever ) ;
It's up to the user to worry about someId, and do whatever he
feels necessary to avoid name clashes, but the effort has never
seemed sufficient to justify a macro. IMHO.)
Also I don't want to instantiate any static variable of D1
.. Dn, so that inside the constructor I may register the
'this' pointer.
I don't know what you mean here so I can't say if it'll solve
your problem.
He's saying basically that he wants something, but refuses to
use any of the known techniques to achieve it.
All I want is the developer should just write the definition
of derived classes, possibly with some constraints and
should not bother about anything else.
What you want is not possible, at least no way I can think of.
It's not really a template metaprogramming problem either.
There might be something you could do with a traits function
explicit instantiation, one that the REGISTER macro would
create, but I don't understand what your problem is well
enough to say.
It seems rather obvious that template metaprogramming couldn't
be a solution in itself, since templates are fully resolved at
compile time, and as I understand it, the system must be open to
classes which are separately compiled. You can't say, I want
this resolved at compile time, but the information won't be
available until link time (or maybe runtime, if dynamic linking
is being used).

Note that if static linking is being used, it should be possible
to insert a small script which generates a source with all of
the information, in a statically initialized table (with
std::find being used for lookup). This can have certain
advantages in some cases (and major disadvantages in others).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jul 16 '08 #5

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

Similar topics

12
by: Dave | last post by:
Would people agree with the statement that to a large degree, using template metaprogramming techniques turns a C++ compiler into a C++ interpreter (but just for the metaprogrammed portions of the...
5
by: Mohammad | last post by:
Hi, Is it possible to disable a method of a template class depending on the typename at compile time? thanks!
2
by: Ganesh | last post by:
I am not sure if the question is relevant to this group. Is there a proof that template metaprogramming is Turing-complete? Is the proof trivial - just replace all the template instantiaion with...
1
by: Mordachai | last post by:
How might I go about creating a template that distinquishes between alternate implementations based on the internal structure of its target datatype? What I want: Initialized<Foo> foo; Where...
7
by: Joe | last post by:
Hi, I found a concept named template metaprogramming that can be used in C+ + code at compile-time. I am a beginner at C++. But I am a programmer on the .NET platform. Do you know if template...
1
by: Ted | last post by:
I have cross posted this to comp.lang.c++ and to sci.math.num- analysis in the belief that the topic is of interest to some in both groups. I am building my toolkit, in support of my efforts in...
5
by: iapx86 | last post by:
My parser project calls for a computed goto (see code below). The C preprocessor delivers the desired result, but is ugly. Template metaprogramming delivers results I do not understand. Can...
3
by: stdlib99 | last post by:
Hi, I have a simple question regarding templates and meta programming. I am going to try and work my way through the C++ Template Metaprogramming, a book by David Abrahams and Aleksey...
12
by: nooneinparticular314159 | last post by:
Hello. If I declare the following: template<int a, int b, int SomeArray> class DoSomething{ public: .. .. ..
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.