Search code examples
c++templatesstaticmetaprogramming

Inputs of a method depending on the template structure


template <typename Stru_>
    class templateClasse{
    public:
    
      using stru = Stru_;
    
      static void method_0(int sk, int sl){
        printf("class templateClass method_0 sk: %d sl: %d\n", sk, sl);
      }
    
      static void method_1(int a){
        if (stru::isvec){
          method_0(0, a);
        } else{
          method_0(a, 0);
        }
      }
    };

I would like to change the inputs in the method_0 depending on the bool stru::isvec as the code shows, meanwhile, I wish that the choice of if (stru::isvec) else branch is made during compilation rather than the runtime. My questions are:

  1. Does this code choose the method_0 during compilation?
  2. The code is successfully compiled only when I add the keyword staticbefore those two methods. Why should staticworks in this case? Usally, my understanding of staticis like this:

These static variables are stored on static storage area, not in stack.

and I know when I use static const int tmp = 50; this tmp is computed in compiled-time. So can static be roughly understood as a keyword to help compile-time computation?

  1. Do we have other solutions in this case?

Thanks in advance!


Solution

    1. Does this code choose the method_0 during compilation?

    No, the dispatch happens at run-time.

    You can use constexpr if (since C++17) to make the dispatch performed at compile-time.

    void method_1(int a){
      if constexpr (stru::isvec){
        method_0(0, a);
      } else{
        method_0(a, 0);
      }
    }
    
    1. The code is successfully compiled only when I add the keyword static before those two methods.

    No, you don't have to. This is a side issue; in class definition static is used to declare static members that are not bound to class instances.

    LIVE

    With C++11, you can perform overloading with SFINAE. E.g.

    template <typename T = Stru_>
    typename std::enable_if<T::isvec>::type method_1(int a){
       method_0(0, a);
    }
    template <typename T = Stru_>
    typename std::enable_if<!T::isvec>::type method_1(int a){
       method_0(a, 0);
    }
    

    LIVE