0

I am a complete noob to meta-programming and my question is really simple,but I haven't found a simple answer.Something similar is answered here but I couldn't translate it to my needs.

I have a class like this

class Program {

 public:

   Program(){}

   SetMatrixUniform(){

      CallSomeMethodX();

   }

    ~Program(){}

};

But I have scenarios where I need the same class with the same methods but calling different functions in their bodies.Something like this:

 class Program {

 public:

   Program(){}

   SetMatrixUniform(){

      CallSomeMethodY();

   }

    ~Program(){}

};

I would like to have template interface to such a class with "true" parameter to select what to put into class member methods in compile time,instead of maintaining 2 such classes.

something like this:

  Program<true> myProg;   ///expands    CallSomeMethodX(); into  SetMatrixUniform()

while :

  Program<false> myProg;   ///expands    CallSomeMethodY(); into  SetMatrixUniform()

I have seen examples where class variations are declared and then through specialization the final class extends one of those.I would like to do it without using inheritance as the performance is really important here.

Community
  • 1
  • 1
Michael IV
  • 11,016
  • 12
  • 92
  • 223
  • 1
    You may be interested in [this blog entry](http://dev-jungle.blogspot.de/2014_02_01_archive.html). That's the way I'm usually doing to solve this kind of problem. Same works for e.g. selection of particular base classes providing the behavior implementation. – πάντα ῥεῖ Apr 02 '14 at 11:09

1 Answers1

2

This can be solve using template specialization

We first declare Programm as a template taking a bool parameter:

template<bool B>
struct Programm
{
    struct SetMatrixUniform()
    {
         std::cout << "General / Generic Implementation" << std::endl;
    }
};

Now we can provide another implementation/specialization for a more concrete case, e.g if B == true

template<>
struct Programm<true>
{
    void SetMatrixUniform()
    {
       std::cout << "Sepcific Implementation For B == true" << std::endl;
    }
};

As bool can only hold two states: true and false, the first implementation will be used if the template is instantiated with false and the second if the template is instantied with true.


This solution however is kind of verbose and requires you two reimplement much of your functionality. If you simply need different behaviour in just some methods, you can also directly compare B. E.g:

template<bool B>
struct Programm
{
    void SetMatrixUniform()
    {
        if(B == true)
            //...
        else
            //...
    }
};
Sebastian Hoffmann
  • 11,127
  • 7
  • 49
  • 77
  • So if the Program class has like 40 functions it means I need to have 40 for your first and 40 for your second structure? Can't it be resolved at the method level? – Michael IV Apr 02 '14 at 11:12
  • So your second example will effectively generate only one of the method and drop the conditional branching? – Michael IV Apr 02 '14 at 11:16
  • @MichaelIV Besides my propoesed solution, a common technique also found quite commonly in such cases is to put common behaviour in a base class and make the sepcialization derive from that base class. – Sebastian Hoffmann Apr 02 '14 at 11:16
  • @MichaelIV What do you mean? As `Programm` and `Programm` are two different classes, the second solution will also generate two methods. However in those methods we will find a statement like `if(true == true)` or `if(false == true)`. Any decent compiler will be able to optimize that if condition away. – Sebastian Hoffmann Apr 02 '14 at 11:18
  • @MichaelIV And regarding inheritance: Please learn the facts. Inheritance will not generate any kind of performance overhead if you 1) Dont use polymorphic/virtual methods 2) Dont use RTTI. – Sebastian Hoffmann Apr 02 '14 at 11:21