Templates With Psuedo-Inheritance Design C++ - c++

This question might fall into "wanting the best of all worlds" but it is a real design problem that needs at least a better solution.
Structure needed:
In order of importance, here's the requirements that have me stuck
We need templates, whether on the class or function level. We are highly dependent on template objects in arguments of functions at this point. So if anything leaves the model below, its virtual functions (to my knowledge).
We want to decouple the call from selection. By that we want the user to declare a Math Object and have the background figure it out, preferably at runtime.
We want there to be a default, like shown in the above diagram.
In my company's program, we have a crucial algorithm generator that is dependent on both compile-time and runtime polymorphism, namely template classes and virtual inheritance. We have it working, but it is fragile, hard to read and develop and has certain features that won't work on higher optimization levels (meaning we are relying on undefined behavior somewhere). A brief outline of the code is as follows.
// Math.hpp
#include <dataTypes.hpp>
// Base class. Actually handles CPU Version of execution
template <typename T>
class Math {
// ...
// Example function. Parameters vary in type and number
// Variable names commented out to avoid compile warnings
virtual void exFunc ( DataType<T> /*d*/, float /*f*/ )
{
ERROR_NEED_CODE; // Macro defined to throw error with message
}
// 50+ other functions...
};
//============================================================
// exampleFuncs.cpp
#include<Math.hpp>
template <> void Math<float>::exFunc ( DataType<float> d, float f)
{
// Code Here.
}
Already, we can see some problems, and we haven't gotten to the main issue. Due to the sheer number of functions in this class, we don't want to define all in the header file. Template functionality is lost as a result. Second, with the virtual functions with the template class, we need to define each function in the class anyways, but we just shoot an error and return garbage (if return needed).
//============================================================
// GpuMath.hpp
#include <Math.hpp>
// Derived class. Using CUDA to resolve same math issues
GpuMath_F : Math<float> { ... };
The functionality here is relatively simple, but I noticed that again, we give up template features. I'm not sure it needs to be that way, but the previous developers felt constrained to declare a new class for each needed type (3 currently. Times that by 50 or so functions, and we have severe level of overhead).
Finally, When functionality is needed. We use a Factory to create the right template type object and stores it in a Math pointer.
// Some other class, normally template
template <typename T>
class OtherObject {
Math<T>* math_;
OtherObject() {
math_ = Factory::get().template createMath<T> ();
// ...
}
// ...
};
The factory is omitted here. It gets messy and doesn't help us much. The point is that we store all versions of Math Objects in the base class.
Can you point me in the right direction for other techniques that are alternative to inheritance? Am I looking for a variation of Policy Design? Is There a template trick?
Thanks for reading and thanks in advance for your input.

As has been discussed many times before, templates with virtual features don't jive well together. It is best to choose one or the other.
Approach 1 : Helper Class
The first and best option we have so far does just that, opting out of the virtual features for a wrapper class.
class MathHelper {
Math cpuMath;
GpuMath gpuMath;
bool cuda_; //True if gpuMath is wanted
template <typename T>
void exFunc ( DataType<T> d, float f )
{
if (cuda_)
gpuMath.exFunc( d, f );
else
cpuMath.exFunc( d, f );
}
// 50+ functions...
};
First, you might have noticed that the functions are templated rather than the class. It structurally is more convenient.
Pros
Gains full access to templates in both CPU and GPU classes.
Improved customization for each and every function. Choice of what is default.
Non-invasive changes to previous structure. For example, if this MathHelper was just called Math and we had CpuMath and GpuMath as the implementation, the instantiation and use can almost be the same as above, and stay exactly the same if we let Factory handle the MathHelper.
Cons
Explicit if/else and declaration of every function.
Mandatory definition of every function in MathHelper AND at least one of the other Math objects.
As a result, repeated code everywhere.
Approach 2: Macro
This one attempts to reduce the repeated code above. Somewhere, we have a Math function.
class Math {
CpuMath cpuMath;
GpuMath gpuMath;
// Some sort of constructor
static Math& math() { /*static getter*/ }
};
This math helper uses a static getter function similar to Exam 1 shown here. We have base class CpuMath that contains no virtual functions and derived class GpuMath. Again, templating is on function level.
Then from there, any time we want a math function we use this macro:
#define MATH (func, ret...) \
do { \
if (math.cuda_) \
ret __VA_OPT__(=) math().cuda.func; \
else \
ret __VA_OPT__(=) math().cpu.func; \
} while (0)
Pros
Remove repeat code of previous wrapper.
Again, full power of templates unlocked
Cons
Not as customizable as above wrapper
Initially much more invasive. Every time a Math function is accessed, it has to change from val = math_.myFunc(...), to MATH (myFunc(...), val). Because editors don't do good error checking on macros, this has potentially to cause many errors in the editing process.
Base class must have every function derived class have, since it is default.
Again, if any other creative ways around to implement this design would be appreciated. I found this to be a fun exercise either way, and would love to continue learning from it.

Related

Genericity VS Polymorphic data structures [duplicate]

I am trying to get my head around applying template programming (and at some future point, template metaprogramming) to real-world scenarios. One problem I am finding is that C++ Templates and Polymorphism don't always play together the way I want.
My question is if the way I'm trying to apply template programming is improper (and I should use plain old OOP) or if I'm still stuck in the OOP mindset.
In this particular case, I am trying to solve a problem using the strategy-pattern. I keep running into the problem where I end up wanting something to behave polymorphically which templates don't seem to support.
OOP Code using composition:
class Interpolator {
public:
Interpolator(ICacheStrategy* const c, IDataSource* const d);
Value GetValue(const double);
}
void main(...) {
Interpolator* i;
if (param == 1)
i = new Interpolator(new InMemoryStrategy(...), new TextFileDataSource(...));
else if (param == 2)
i = new Interpolator(new InMemoryStrategy(...), new OdbcDataSource(...));
else if (param == 3)
i = new Interpolator(new NoCachingStrategy(...), new RestDataSource(...));
while (run) {
double input = WaitForRequest();
SendRequest(i->GetValue(input));
}
}
Potential Template Version:
class Interpolator<class TCacheStrategy, class TDataSource> {
public:
Interpolator();
Value GetValue(const double); // may not be the best way but
void ConfigCache(const& ConfigObject); // just to illustrate Cache/DS
void ConfigDataSource(const& ConfigObject); // need to configured
}
//Possible way of doing main?
void main(...) {
if(param == 1)
DoIt(Interpolator<InMemoryStrategy, TextFileDataSource>(), c, d);
else if(param == 2)
DoIt(Interpolator<InMemoryStrategy, OdbcDataSource>(), c, d)
else if(param == 3)
DoIt(Interpolator<NoCachingStrategy, RestDataSource>(), c, d)
}
template<class T>
void DoIt(const T& t, ConfigObject c, ConfigObject d) {
t.ConfigCache(c);
t.ConfigDataSource(c);
while(run) {
double input = WaitForRequest();
SendRequest(t.GetValue(input));
}
}
When I try to convert the OOP implementation to a template-based implementation, the Interpolator code can be translated without a lot of pain. Basically, replace the "interfaces" with Template type parameters, and add a mechanism to either pass in an instance of Strategy/DataSource or configuration parameters.
But when I get down to the "main", it's not clear to me how that should be written to take advantage of templates in the style of template meta programming. I often want to use polymorphism, but it doesn't seem to play well with templates (at times, it feels like I need Java's type-erasure generics... ugh).
When I often find I want to do is have something like TemplateType<?, ?> x = new TemplateType<X, Y>() where x doesn't care what X, Y is.
In fact, this is often my problem when using templates.
Do I need to apply one more level of
templates?
Am I trying to use my shiny new power template wrench to
install a OOP nail into a PCI slot?
Or am I just thinking of this all
wrong when it comes to template
programming?
[Edit] A few folks have pointed out this is not actually template metaprogramming so I've reworded the question slightly. Perhaps that's part of the problem--I have yet grok what TMP really is.
Templates provide static polymorphism: you specify a template parameter at compile time implementing the strategy. They don't provide dynamic polymorphism, where you supply an object at runtime with virtual member functions that implement the strategy.
Your example template code will create three different classes, each of which contains all the Interpolator code, compiled using different template parameters and possibly inlining code from them. That probably isn't what you want from the POV of code size, although there's nothing categorically wrong with it. Supposing that you were optimising to avoid function call overhead, then it might be an improvement on dynamic polymorphism. More likely it's overkill. If you want to use the strategy pattern dynamically, then you don't need templates, just make virtual calls where relevant.
You can't have a variable of type MyTemplate<?> (except appearing in another template before it's instantiated). MyTemplate<X> and MyTemplate<Y> are completely unrelated classes (even if X and Y are related), which perhaps just so happen to have similar functions if they're instantiated from the same template (which they needn't be - one might be a specialisation). Even if they are, if the template parameter is involved in the signatures of any of the member functions, then those functions aren't the same, they just have the same names. So from the POV of dynamic polymorphism, instances of the same template are in the same position as any two classes - they can only play if you give them a common base class with some virtual member functions.
So, you could define a common base class:
class InterpolatorInterface {
public:
virtual Value GetValue(const double) = 0;
virtual void ConfigCache(const& ConfigObject) = 0;
virtual void ConfigDataSource(const& ConfigObject) = 0;
virtual ~InterpolatorInterface() {}
};
Then:
template <typename TCacheStrategy, typename TDataSource>
class Interpolator: public InterpolatorInterface {
...
};
Now you're using templates to create your different kinds of Interpolator according to what's known at compile time (so calls from the interpolator to the strategies are non-virtual), and you're using dynamic polymorphism to treat them the same even though you don't know until runtime which one you want (so calls from the client to the interpolator are virtual). You just have to remember that the two are pretty much completely independent techniques, and the decisions where to use each are pretty much unrelated.
Btw, this isn't template meta-programming, it's just using templates.
Edit. As for what TMP is, here's the canonical introductory example:
#include <iostream>
template<int N>
struct Factorial {
static const int value = N*Factorial<N-1>::value;
};
template<>
struct Factorial<0> {
static const int value = 1;
};
int main() {
std::cout << "12! = " << Factorial<12>::value << "\n";
}
Observe that 12! has been calculated by the compiler, and is a compile-time constant. This is exciting because it turns out that the C++ template system is a Turing-complete programming language, which the C preprocessor is not. Subject to resource limits, you can do arbitrary computations at compile time, avoiding runtime overhead in situations where you know the inputs at compile time. Templates can manipulate their template parameters like a functional language, and template parameters can be integers or types. Or functions, although those can't be "called" at compile time. Or other templates, although those can't be "returned" as static members of a struct.
I find templates and polymorphism work well toegther. In your example, if the client code doesn't care what template parameters Interpolator is using then introduce an abstract base class which the template sub-classes. E.g.:
class Interpolator
{
public:
virtual Value GetValue (const double) = 0;
};
template<class TCacheStrategy, class TDataSource>
class InterpolatorImpl : public Interpolator
{
public:
InterpolatorImpl ();
Value GetValue(const double);
};
void main()
{
int param = 1;
Interpolator* interpolator = 0;
if (param==1)
interpolator = new InterpolatorImpl<InMemoryStrategy,TextFileDataSource> ();
else if (param==2)
interpolator = new InterpolatorImpl<InMemoryStrategy,OdbcDataSource> ();
else if (param==3)
interpolator = new InterpolatorImpl<NoCachingStrategy,RestDataSource> ();
while (true)
{
double input = WaitForRequest();
SendRequest( interpolator->GetValue (input));
}
}
I use this idiom quite a lot. It quite nicely hides the templatey stuff from client code.
Note, i'm not sure this use of templates really classes as "meta-programming" though. I usually reserve that grandiose term for the use of more sophisticated compile-time template tricks, esp the use of conditionals, recursive defintions etc to effectively compute stuff at compile time.
Templates are sometimes called static (or compile-time) polymorphism, so yes, they can sometimes be used instead of OOP (dynamic) polymorphism. Of course, it requires the types to be determined at compile-time, rather than runtime, so it can't completely replace dynamic polymorphism.
When I often find I want to do is have something like TemplateType x = new TemplateType() where x doesn't care what X,Y is.
Yeah, that's not possible. You have to do something similar to what you have with the DoIt() function. Often, I think that ends up a cleaner solution anyway (you end up with smaller functions that do just one thing each -- usually a good thing). But if the types are only determined at runtime (as with i in the OOP version of your main function), then templates won't work.
But In this case, I think your template version solves the problem well, and is a nice solution in its own right. (Although as onebyone mentions, it does mean code gets instantiated for all three templates, which might in some cases be a problem)

Passing Arguments to Function using Template Types

I'm pushing IMO the limits of C++template programming. The system is an Arduino but my attempt is applicable to any microcontroller system.
I define Pins using a template class with an 'int' parameters
template<const int pin>
struct Pin {
Pin() { mode(pin, 0); }
};
template<const int pin>
class PinOut : public Pin<pin> {};
I can create template classes to use PinOut like:
template<typename F>
class M {
public:
M() { }
F mF;
};
M<PinOut<1>> m1;
template<int F>
class N {
public:
N() { }
Pin<F> mF;
};
N<1> n1;
But I'd like to not use templates in the classes that use PinOut. This is illustrative of my thinking showing possible approaches but clearly doesn't work.
class R {
public:
R(const int i) {
}
PinOut<i> mF; // create template instance here
};
R r1(1); // what I'd like to able to do
I recognize the problem is creating a type inside class R.
The other possibility is instantiating a PinOut variable and passing it in but again passing and creating a type inside the class is a problem. Something like this:
class S {
public:
S(PinOut<int>& p) { } // how to pass the type and instance
PinOut<p>& mF; // and use it here
};
PinOut<1> pp;
S s1(pp);
Sorry if this sound abrupt but please don't ask why or what I'm trying to do. This is an experiment and I'm pushing my understanding of C++ especially templates. I know there are other approaches.
Yes, any function that takes that type must itself be a template.
But is the entire family of Pin related in a way that some thing are meaningful without knowing T? This can be handled with a base class that's a non-template. The base class idea is especially handy because it can contain virtual functions that do know about T. This lets you switch between compile-time and run-time polymorphism on the fly as desired. Taken to an extreme, that becomes the weaker idea with the same syntax of "Generics" as seen in Java and .NET.
More generally, this is a concept known as type erasure. You might search for that term to find out more. It is designed into libraries in order to keep common code common and prevent gratuitous multiplication of the same passage though multiple instantiations.
In your case, pin is a non-type argument, which is something Generics don't even do. But it may not really affect the type much at all: what about the members change depending on pin? This might be an array bound, or a compile-time constant used to provide compile-time knowledge and optimization, or there for the sole purpose of making the type distinct.
All of these cases are things can be dealt with at run-time, too. If it's for the sole purpose of making the type distinct (e.g. make the compiler check that you pass time values and distance values to the correct parameters) then the real guts are all in a base class that omits the distinctiveness.
If it's an array bound or other type difference that can be managed at run-time, then again the base class or an adapter/proxy can do it at run-time. More generally a compile-time constant that doesn't affect the class layout can be known at run-time with the same effect, just less optimization.
From your example, that it is sensible to make the pin a constructor argument, the class could be implemented in the normal way with run-time configuration. Why is it a template? Presumably for compile-time checking to keep separate things separate. That doesn't cause them to work in different ways, so you want that compile-time part to be optional. So, this is a case where a base class does the trick:
class AnyPin
{
public:
AnyPin (int pin); // run-time configuration
};
template <int pin>
class Pin : public AnyPin { ⋯ };
Now you can write functions that take AnyPin, or write functions that take Pin<5> and get compile-time checking.
So just what does pin do to the class, in terms of its layout and functionality? Does it do anything that makes it unacceptable to just implement it as a run-time constructor value?
You ask that we don't inquire as to what you're trying to do, but I must say that templates have certain features and benefits, and there must be some reason for making it a template. Speaking simply in language-centric terms, did I miss something with the above analysis? Can you give a C++-programming reason for wanting it to be a template, if my summary didn't cover it? That may be why you didn't get any answers thus far.

Run-time polymorphism design and strategies with CRTP

In my work I have a lot of loops with many inner function calls; performance is critical here, and the overhead of virtual function calls is unacceptable, so I try to avoid dynamic polymorphism by using CRTP, like so:
template<class DType>
struct BType {
DType& impl(){ return *static_cast<DType*>(this); }
void Func(){ impl().Func(); }
};
struct MyType : public BType<MyType> {
void Func(){ /* do work */ }
};
template<class DType>
void WorkLoop(BType<DType>* func){
for (int i=0;i<ni;++i){ func->func(); }
}
struct Worker {
void DoWork(){ WorkLoop(&thing) };
private:
MyType thing;
};
Worker worker;
worker.DoWork();
Aside: is the correct way to actually use a CRTP class? Now I need the actual type to depend on a runtime user option, and normally dynamic polymorphism with an abstract base class / strategy pattern would be the right design, but I can't afford the virtual function calls. One way to do this seems to be with some branching:
struct Worker {
void DoWork(){
if (option=="optionA"){
TypeA thing;
WorkLoop(thing); }
else if (option=="optionB"){
TypeB thing;
WorkLoop(thing); }
...
But this seems like a lousy design. Passing it as a template parameter here (or using policy based design) seems like an option:
template<class T>
struct Worker {
void DoWork(){ WorkLoop(&thing) };
T thing;
};
if (option=="optionA"){
Worker<TypeA> worker; worker.DoWork() } ...
but here worker only has scope in the if branch, and I'd need it to have a life the length of the program. Additionally, the relevant user options would probably specify 4+ "policies", each of those with several options (say 4), so it seems like you'd quickly have a nasty problem where a templated class could take 1 of 4*4*4*4 template combinations.
Also, moving the loop logic into the types is not an option - if it were the virtual function call overhead would be negligible and I'd use normal polymorphism. The actual control of the loops could be rather complicated and will vary at runtime.
Would this suggest that I should try and build a custom iterator and pass that as a function argument and use normal polymorphism, or would this incur similar overhead?
What is a good design for selecting classes at run-time without resorting to pointers to abstract base classes?
You have a classic problem of runtime-to-compile-time dispatch: "Additionally, the relevant user options would probably specify extra policies, each of those with several options". Your code has to support many combinations of options which you do not know at compile time.
It means you have to write some code for every possible combination and then dispatch user's choice onto one of the combinations. It implies you have to have some ugly and not-so-efficient piece of code where you parse user's runtime decisions and dispatch them onto predefined templates.
To keep efficiency as high as possible you want to do this dispatch at very high-level, as close to entry points as possible. On the other side, your low-level code can templatized as much as you like.
It means dispatch can have several down-steps from non-template code to mix of templates and options to fully templetized.
Usually it is achieved better with tags and policies, not CRTP, but it depends closely on your algorithms and options.

"Redirect" class member functions?

Basically I found myself today writing lots of code like below:
#define VAL_1 0
#define VAL_2 1
class A {
public:
void memberA();
void memberB();
...
void write(uin32_t address);
}
void
A::
memberA() {
this->write(VAL_1);
}
void
A::
memberB() {
this->write(VAL_2);
}
...
So basically, I have "pretty" names memberA, memberB for some task that really only does call the same function write with a different argument. The values VAL_0 and VAL_1 are not necessarily known to code using my class. Neither is the implementation detail behind memberA or memberB, although writemight be going public at some point.
Basically, now I'm repeating the same line of code this->write(...) over and over again. I'm looking for a solution that bypasses this step and calls the respective write immediately. A kind of passing on of the function arguments somewhat like a C++ constructor from a base class, possibly with matching arguments:
#define VAL_1 0
#define VAL_2 1
class A {
public:
bool memberA() : write(VAL_1);
bool memberB() : write(VAL_2);
...
bool write(uin32_t address);
}
I'm wondering whether there might be something in Boost.Bind or some clever template-coding that lets me achieve this kind or thing?
Thanks,
FRob
If you make your memberX functions inline in the class definition, and if you avoid the redundant this reference, then you don't have too much extra to write:
Your desired (incorrect) syntax:
bool memberA() : write(VAL_1);
The actual (correct) syntax:
bool memberA() { return write(VAL_1); }
If you want to minimize your repetitive code, you could use the pre-processor:
#define F(l, n) bool l() { return write(n); }
F(memberA, VAL_1)
F(memberB, VAL_2)
#undef F
Further, you could use the preprocessor token-pasting operator ##:
#define F(l, n) bool member##l() { return write(VAL_##n); }
F(A, 1)
F(B, 2)
#undef F
Without fully understanding what you are after (I got confused about the last part involving constructors), I think you might be trying a little too hard to make the syntax easier on your clients.
... how about simply:
class A {
public:
enum Value {val1, val2, val3, val4, etc};
bool write(Value val);
};
It's good that you are trying to establish an easier syntax, but you also have to avoid the danger of monolithism. Monolithic classes are something that I strongly believe is one of the most common mistakes in object-oriented design. Sutter goes into this in detail in C++ Coding Standards and on gotw: http://www.gotw.ca/gotw/084.htm.
If you have a class with 100 member functions, you probably have about 80 too many.
^ Think about this statement for a while. When you have so many functions, your classes tend to become increasingly hard to manage. It also invites other developers to just keep adding more and more to your class so that its design is never finalized. The result is the never-ending class that just grows and grows with each development cycle with no end in sight. That can easily become a source of bugs, inefficiencies, constant public interface revisions, unit test breakages, and it can go against the general reuse and flexibility of your class. When you have a separate function per value you can pass to another function, you're dangerously treading into that territory.
Trying too hard to avoid syntactical redundancy is usually a mistake. Unfortunately C++ just requires more lengthy syntax in some cases (getting much better with C++11). What you should try to optimize away is logical redundancy. Here calling write method with various values involves no logical redundancy, and the syntactical overhead is barely more than calling different functions for each value you can possibly pass to write.
If these functions do nothing more than simplify the syntax of passing various values, you have to come to the realization that you are also bloating the class's public interface with a whole lot more functions that, if you are in a production environment, you will likely have to document and teach individually. Strive for doing more with less and I think you'll be much better off.
Try to keep this aspect of monolithism in mind as a priority. You might even go so far as to hoist the named constants out of the class definition as non-members, like so:
class A {
bool write(uint32_t address);
};
// elsewhere
static const uint32_t address_val1 = ...;
static const uint32_t address_val2 = ...;
static const uint32_t address_val3 = ...;
There's actually nothing wrong with this design and, in fact, it has more desirable engineering characteristics than the one where you have more class members as it's completely decoupled from your class, making the maintenance of that class easier, its interface simpler to teach and document, and more likely to meet a state of reasonable completion.

C++: Design and cost for heavy multiple inheritance hierarchies

I have a class hierarchy with the following three classes:
template<int pdim >
class Function
{
virtual double operator()( const Point<pdim>& x) const = 0;
};
Which is a function in pdim-dimensional space, returning doubles.
template<int pdim, int ldim >
class NodeFunction
{
virtual double operator()( const Node<pdim,ldim>& pnode, const Point<ldim>& xLoc) const = 0;
};
Which is a function from the ldim-dimensional local space of a node in pdim-dimensional space.
template<int pdim, int ldim, int meshdim >
class PNodeFunction
{
virtual double operator()( const PNode<pdim,ldim,meshdim>& pnode, const Point<ldim>& xLoc) const = 0;
};
Reason 1 for this design: a NodeFunction is more general than a Function. It can always map the local ldim-point point to a pdim-point. E.g an edge (Node with ldim=1) maps the interval [0,1] into pdim-dimensional physical space. That is why every Function is a NodeFunction. The NodeFunction is more general as the NodeFunction is allowed to query the Node for attributes.
Reason 2 for this design: a PNodeFunction is more general than a NodeFunction. Exactly one Node is accociated to every PNode (not vice versa). That is why every PNodeFunction is a NodeFunction. The PNodeFunction is more general as it also has all the context of the PNode which is part of a Mesh (thus it knows all its parents, neighbours, ...).
Summary: Every Function<pdim> is a NodeFunction<pdim, ldim> for any parameter of ldim. Every NodeFunction<pdim, ldim> is a NodeFunction<pdim, ldim, meshdim> for any parameter of meshdim.
Question: What is the best way to express this in C++, such that I can use Function in place of NodeFunction / PNodeFunction, such that the code is fast (it is a high performance computing code), such that the Code works for
The template parameters are not completely independent but rather dependend on each other:
- pdim=1,2,3 (main interest) but it is nice if it works also for values of pdim up to 7.
- 'ldim=0,1,...,pdim'
- 'meshdim=ldim,ldim+1,...,pdim'
To consider the performance, note that obly a few functions are created in the program, but their operator() is called many times.
Variants
I thought about a few ways to implement this (I currently implemented Variant 1). I wrote it down here so that you can tell me about the advanage and disadvantage of these approaches.
Variant 1
Implement the above described inheritance A<dim> inherits from B<dim,dim2> via a helper template Arec<dim,dim2>. In pseudo Code this is
class A<dim> : public Arec<dim,dim>;
class Arec<dim,dim2> : public Arec<dim,dim2-1>, public B<dim,dim2>;
class Arec<dim,0> : public B<dim,dim2>;
This is applied both to inherit Function from NodeFunction and NodeFunction from PNodeFunction. As NodeFunction inherits roughly O(pdim^2) times from PNodeFunction how does this scale? Is this huge virtual table bad?
Note: In fact every Function should also inherit from VerboseObject, which allows me to print debugging information about the function to e.g. std::cout. I do this by virtually inheritung PNodeFunction from VerboseObject. How will this impact the performance? This should increase the time to construct a Function and to print the debug information, but not the time for operator(), right?
Variant 2
Don't express the inheritance in C++, e.g. A<dim> doesn inherit from B<dim,dim2> bur rather there is a function to convert the two
class AHolder<dim,dim2> : public B<dim, dim> {
}
std::shared_pointer< AHolder<dim,dim2> > interpretAasB( std::shared_pointer< AHolder<dim> >)
[...]
This has the disadvanate that I can no longer use Function<dim> in place of NodeFunction<dim> or PNodeFunction<dim>.
Variant 3
What is your prefered way to implement this?
I don't comprehend you problem very well; that might be because I lack specific knowledge of the problem domain.
Anyway it seems like you want to generate a hierarchy of classes, with Function (most derived class) at the bottom, and PNodeFunction at the top (least derived class).
For that I can only recommend Alexandrescu's Modern C++ design book, especially the chapter on hierarchy generators.
There is an open source library stemming from the book called Loki.
Here's the part that might interest you.
Going the generic meta-programming way might be the hardest but I think it will result in ease of use once setup, and possibly increased performance (that is always to be verified by the profiler) compared to virtual inheritance.
In any case I strongly recommend not inheriting from the Verbose object for logging, but rather having a separate singleton logging class.
That way you don't need the extra space in the class hierarchy to store a logging object.
You could have only the least derived class inherit from the Verbose object but your function classes are not logging objects; they use a logging object (I may be a bit pedantic here). The other problem is if you inherit multiple times from that base class, you'll end up with multiple copies of the logging object and have to use virtual inheritance to solve it.