Reputation: 520
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.
Upvotes: 0
Views: 2052
Reputation: 217065
You might want something like:
template <bool b1, bool b2, bool b3, bool b4>
void f()
{
// Your method.
std::cout << b1 << b2 << b3 << b4 << std::endl;
}
template <std::size_t...Is>
void call_f_helper(int i, std::index_sequence<Is...>)
{
using f_t = void();
f_t* fs[] = {&f<(Is >> 0) & 1, (Is >> 1) & 1, (Is >> 2) & 1, (Is >> 3) & 1>...};
fs[i]();
}
// The runtime dispather
void call_f(bool b1, bool b2, bool b3, bool b4)
{
call_f_helper(b1 << 0 | b2 << 1 | b3 << 2 | b4 << 3, std::make_index_sequence<16>());
}
Upvotes: 3
Reputation: 40849
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:
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.
Upvotes: 2