generalizing template code

  • Thread starter Aleksandr Dubinskiy
  • Start date
A

Aleksandr Dubinskiy

Hello folks,
This question is a bit involved, so I am posting the code on the web,
instead of cutting and pasting it on the email.
http://www.cis.ohio-state.edu/~dubinski/Code/
I think the code is pretty clear, just there's a lot of it, so
I'll try to guide you thru it.

Here's the layout. There are 5 packages / namespaces:
Updater, Energizer, Converter, Proposal, and finally Diffuser

Energizer, Converter, and Updater are independent.
Proposal knows about all three of them, and Diffuser
knows about all other packages.
Start looking with Diffuser.

In DiffuserExt.h you can see the declarations for
classes APrime and MuCenter. You should notice that
the data memebers look similar, but are actually of
different template instantiations. Similarly in
DiffuserSF.h you will see the declarations for classes
Param, and Coeff, which have the same property.

Then if you look at the definitions for the
constructors of these classes (in DiffuserSF.cpp and DiffuserExt.cpp),
you'll see they're
almost identical in the feel and look.

And this is what I'm trying to take care of. I want to
be able to unify these classes "under one roof". I want
the diffuser interface to have 3 members: _prop,
_conv, and _upd. It's just that these are different
template instantiations, and they don't conform to the
same interface. I would like them to, but I don't see
how.

This becomes especially clear when you try to unify
Converters (see files TinyConverter.h and
Converters.h). Because of the templates, I don't see
how to make them conform to the same interface and
treat them uniformly. This is also begging for some creative design pattern,
but I am afraid I need handle the issue with the templates first.

Well, I hope this makes sense.
Does anybody see a nice solution here?

Alex
 
V

Victor Bazarov

Aleksandr Dubinskiy said:
This question is a bit involved, so I am posting the code on the web,
instead of cutting and pasting it on the email.
http://www.cis.ohio-state.edu/~dubinski/Code/
I think the code is pretty clear, just there's a lot of it, so
I'll try to guide you thru it.

Here's the layout. There are 5 packages / namespaces:
Updater, Energizer, Converter, Proposal, and finally Diffuser

Energizer, Converter, and Updater are independent.
Proposal knows about all three of them, and Diffuser
knows about all other packages.
Start looking with Diffuser.

In DiffuserExt.h you can see the declarations for
classes APrime and MuCenter. You should notice that
the data memebers look similar, but are actually of
different template instantiations. Similarly in
DiffuserSF.h you will see the declarations for classes
Param, and Coeff, which have the same property.

Then if you look at the definitions for the
constructors of these classes (in DiffuserSF.cpp and DiffuserExt.cpp),
you'll see they're
almost identical in the feel and look.

And this is what I'm trying to take care of. I want to
be able to unify these classes "under one roof". I want
the diffuser interface to have 3 members: _prop,
_conv, and _upd. It's just that these are different
template instantiations, and they don't conform to the
same interface. I would like them to, but I don't see
how.

This becomes especially clear when you try to unify
Converters (see files TinyConverter.h and
Converters.h). Because of the templates, I don't see
how to make them conform to the same interface and
treat them uniformly. This is also begging for some creative design pattern,
but I am afraid I need handle the issue with the templates first.

Well, I hope this makes sense.
Does anybody see a nice solution here?

I don't. But I looked at your code and (a) it's pretty convoluted,
you could at least try to straighten it up and (b) here is a couple
suggestions:
---------------------------------------------- in DiffuserExt.h
template<class P, class C, class U>
class PI : public PatronInterface
{
P* prop;
C* conv;
U* upd;
public:
PI(Patron::pInstance* other);
virtual void diffuse(double, EnergyGetter*);
};

typedef PI<Proposal::proposalABCD,
Converter::TinyToABCD,
Updater::AprimeUpdater> APrime;

typedef PI<Proposal::proposalGridWrap,
Converter::TinyTo1D<Wrap>,
Updater::MuCenterUpdater> MuCenter;
--------------------------------------------------- in DiffuserSF.h
template<class P, class C, class U>
class SFPI : public SFParticularInterface
{
P* prop;
C* conv;
U* upd;
public:
SFPI(BaseLevel::SFDynamic*);
virtual void diffuse_one(double, EnergyGetter*, int);
};

typedef SFPI<Proposal::proposalGridMSPMusOnly,
Converter::TinyToTripletL,
Updater::paramUpdater> MusOnly;

typedef SFPI<Proposal::proposalGridMSP,
Converter::TinyToTripletL,
Updater::paramUpdater> Param;

typedef SFPI<Proposal::proposalABCD,
Converter::TinyToABCD,
Updater::CoeffUpdater> Coeff;
----------------------------------------------------------------
Is that what you meant?

I am not going got comment on your code much, but one thing I'd
like to suggest: do not use leading underscores. They do not make
the code more readable. Also, unless parameter names carry any
significance, leave them out of the function declaration.

If you have more particular questions, do ask.

Victor
 
V

Victor Bazarov

Aleksandr Dubinskiy said:
Thanks Victor,

Well, your template solution certainly helps to reduce the amount of code.

:) That's what the templates are for...
By the way the constructors for classes MuCenter and APrime are different,
so don't I need to keep them as classes instead of using just using
typedefs? Or is there a way to specify a constructor for each particular
typedef?

No, there probably isn't any way. Unless you specialise the
constructors (and not the rest of the classes) or figure out
a way to extract the difference and execute it outside the
constructor...
But mostly I'm looking for a solution, which would make them APrime and
MuCenter interchangeable at runtime?

Not sure what you mean by that. Two classes, both deriving
from the same base class -- you could probably use polymorphism
here, no?
What I really want to be able to do is
to specify subclasses from the outside like this:

class PartonInterface {
PartonInterface(
Proposal::proposalTemplate* p,
Converter::TinyConverter* c,
Updater::StateUpdater* u) {
prop=p; conv=c; upd=u;
}
}

Perhaps you need to merge your multiple Proposals, Converters,
Updaters, into their own hierarchies and also employ polymorphism
there...
Of course this won't work, since all of the interfaces (p,c, u) are
templates, but I'm looking for a workaround, perhaps some kind of boost::any
package or void pointers.

Well, without knowing your model, I don't think I can recommend
you any particular solution. Take a look at the "Modern C++ Design"
by Alexandrescu. And read about "Policy-based design" or "Policy-
based programming".

Victor
 
A

Aleksandr Dubinskiy

Not sure what you mean by that. Two classes, both deriving
from the same base class -- you could probably use polymorphism
here, no?

Yes, I'm already using polymorphism
Perhaps you need to merge your multiple Proposals, Converters,
Updaters, into their own hierarchies and also employ polymorphism
there...
It was already polymorphic.

I think I've come to a satisfactory solution in my code. In case you're
curious, the updated files are up on. Further input on design and style is
appreciated.

http://www.cis.ohio-state.edu/~dubinski/Code/

Thanks,
Aleks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top