Search code examples
c++templatesmetaprogramming

Conditional compilation and non-type template parameters


I am having trouble understanding non-type template arguments and was hoping someone could shed light on this.

#include <iostream>

template<typename T, int a>
void f() {
  if (a == 1) {
    std::cout << "Hello\n";
  } else {
    T("hello");
  }
}

int main() {
  f<int, 1>;
}

When I compile this, I get an error saying:

/tmp/conditional_templates.cc:13:12:   required from here
/tmp/conditional_templates.cc:8:5: error: cast from ‘const char*’ to ‘int’ loses precision [-fpermissive]
     T("hello");
     ^

But, can't the compiler detect that the non-type argument "a" is 1 and hence the else branch won't be taken? Or is that too much to expect? In which case, how do I accomplish something like this?


Solution

  • Try this instead:

    #include <iostream>
    template<typename T, int a>
    struct A {
        void f() {
            T("hello");
        }
    };
    
    template<typename T>
    struct A<T,1> {
        void f() {
            std::cout << "Hello\n";
        }
    };
    
    
    int main() {
      A<int,1> a;
      a.f();
      A<int,2> b;
      b.f();
    }
    

    Now, this uses partial template specialization in order to provide alternative implementations for specific values of the template parameters.

    Note that I've used a class, because function templates cannot be partially specialized