Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ template specialization based on compile time value

I'm feeling my way into template meta-programming, slowly and I'm not sure how to implement the following:

// hpp file
enum MyEnum { Alive = 0, Dead };
class A {
    public:
        template<typename T, typename O, MyEnum ls>
        static int Register();
};

// elsewhere in the code...
A::Register<IType1, Type1, Dead>();

At compile time I will know what enum value the third template type is (compile-time invariant), either Dead or Alive. Is it possible to define two bodies for the Register function, something like:

// desired hpp file
template<typename T, typename O, Alive>
int Register();

template<typename T, typename O, Dead>
int Register();

// corresponding desired .inc file
template<typename T, typename O, Alive>
int Register() { // Alive specific implementation ...  }

template<typename T, typename O, Dead>
int Register() { // Dead specific implementation ...  }

I have taken a look at: C++ Template Specialization with Constant Value

but I have not been able to figure out how to make it apply to this situation.

like image 493
Short Avatar asked May 22 '12 02:05

Short


People also ask

Are templates compile time or runtime?

All the template parameters are fixed+known at compile-time. If there are compiler errors due to template instantiation, they must be caught at compile-time!

How many times is template code compiled?

In general, yes, template classes are usually compiled every time they're encountered by the compiler.

Is template a compile time mechanism?

Templates are the feature that supports generic programming in C++, which are compile time mechanism and there is no runtime overhead associated with using them.

What is the difference between generic class template and specialization template?

Key differences between generics and C++ templates: Generics are generic until the types are substituted for them at runtime. Templates are specialized at compile time so they are not still parameterized types at runtime. The common language runtime specifically supports generics in MSIL.


1 Answers

Very late to the party here, but.

A way to do this that I think is conceptually simpler and also easier to read is simply making the different values of your enum different types (inside a namespace, to keep it clean), and take advantage of (template) function overloading:

namespace State {
  struct Dead {};
  struct Alive {};
}

template<typename T, typename O>
int Register(State::Dead) {
   return 1;
}

template<typename T, typename O>
int Register(State::Alive) {
   return 2;
}

You call them like this:

int main() {
   Register<int,int>(State::Dead());
   Register<int,int>(State::Alive());
   return 0;
}
like image 165
blue Avatar answered Oct 26 '22 12:10

blue