c ++ bool模板避免if语句

时间:2016-10-28 19:41:06

标签: c++ templates if-statement boolean

当我处理模板bool函数时,我正在寻找一种避免if语句的方法 下面的代码显示了我的情况的简化。

#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;   
}

我不想将b作为函数f()的参数传递,因为在实际应用程序中,我对性能感兴趣,我需要检查b的值关键代码部分
我想要一种方法来写:f<b>();
但这样做,我得到以下错误:
error: the value of ‘b’ is not usable in a constant expression

由于在我的应用程序中我有 4 bool模板,我想避免列出这四个的所有组合,例如:

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

还有办法吗?是否存在我可以用某种方式使用的快捷方式?
我还尝试使用if语句快捷方式f<(b?true:false)>();,但我收到了上面显示的相同错误。

2 个答案:

答案 0 :(得分:2)

我想我明白你想做什么。您需要一个查找表,它需要一堆开/关标志并运行模板的特定实例...

这可能有点超出了快速回答中可以做到的事情。你需要一些温和的元编程。我开始的地方是:

  1. 实现一个元编程,创建一组n个标志的排列。
  2. 实现constexpr函数,将一系列标志转换为位掩码。您将在运行时和编译时使用它。
  3. 实现一个元程序,它将根据bool标志为您提供指向实例化的函数指针。
  4. 实现metaprogram / constexpr函数,该函数生成由位掩码索引的此类指针数组。
  5. 在运行时使用布尔值调用。
  6. 实施可能需要几个小时,但不应该那么难。

    您的原始问题似乎是将运行时值转换为编译时值,这根本不可能。但是你可以实现一个跳转表,这样你就不必自己手写每个排列。你应该问自己,不管它是否真的值得,因为最终结果会更难维护,特别是如果你的团队充满了初级开发者 - 我现在假设你是这样。很多资深开发人员也会在山上看到这种事情。

    哦,你根本不会看到任何性能提升。简介,不要假设。

答案 1 :(得分:2)

您可能需要以下内容:

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>());  
}

Demo