Draxent Draxent - 1 month ago 6
C++ Question

c++ bool template avoiding if statement

I'm looking a way to avoid if-statement when I'm dealing with template bool function.

Code below shows a simplification of my situation.

#include <iostream>
#include <string>

template<bool var>
void f(){
std::cout << (var ? "TRUE" : "FALSE") << std::endl;
}

int main(int argc, char* argv[]){
const bool b = (std::string(argv[1]).compare("TRUE") == 0);
if (b) f<true>();
else f<false>();
return 0;
}


I don't want to pass
b
as parameter of function
f()
because, in the real application, I am interested in performance and I need to check the value of
b
in a critical code section.

I would like a way to write something like:
f<b>();


But doing so, I obtain the following error:

error: the value of ‘b’ is not usable in a constant expression


Since in my application I have 4 bool templates, I would like to avoid to list all the combination of those four, like:

if(b1 && b2 && b3 && b4) f<true,true,true,true>();
else if (b1 && b2 && b3 && !b4) f<true,true,true,false>();
...


There is a way around? Does exists a shortcut that I can use in some way?

I tried also to use the if-statement shortcut
f<(b?true:false)>();
,
but I received the same error shows above.

Answer

I think I understand what you want to do. You want a lookup table that takes a bunch of on/off flags and runs a specific instantiation of a template...

It's possible but a bit beyond what can just be done in a quick answer. You'll need some moderate metaprogramming. Where I'd start is:

  1. Implement a metaprogram that creates a set of permutations of n flags.
  2. Implement a constexpr function that converts a series of flags into a bitmask. You'll use it both at runtime and compile-time.
  3. Implement a metaprogram that will give you a function pointer to the instantiation based on bool flags.
  4. Implement a metaprogram/constexpr function that generates an array of such pointers indexed by the bitmask.
  5. Call at runtime with your boolean values.

It will probably take a couple hours to implement but shouldn't be THAT hard.

What your original question seemed to expect was converting a runtime value into a compile-time value and that's simply impossible. But you can implement a jump table such that you don't have to hand write each permutation yourself. You should ask yourself though whether it's really worthwhile because the end result is going to be harder to maintain, especially if your team is full of junior devs--which I am assuming at this point you are. A lot of senior devs run for the hills on seeing this kind of thing too.

Oh, and you're not necessarily going to see any performance improvement at all. Profile, don't assume.