c++ bool模板避免if语句

c++ bool template avoiding if statement

本文关键字:if 语句 bool c++      更新时间:2023-10-16

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

#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)>();
,但我收到了相同的错误显示上面。

您可能想要这样:

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

我想我明白你想做什么。你想要一个查找表,它接受一堆on/off标志,并运行模板的特定实例化…

这是可能的,但有点超出了快速回答所能做到的。您将需要一些适度的元编程。我从这里开始:

  1. 实现一个创建n个标志的排列集的元程序。
  2. 实现constexpr函数,将一系列标志转换为位掩码。您将在运行时和编译时使用它。
  3. 实现一个元程序,它会给你一个基于bool标志的实例化函数指针。
  4. 实现一个元程序/constexpr函数,生成由位掩码索引的指针数组。
  5. 在运行时调用布尔值。

这可能需要几个小时来实现,但不应该那么难。

你最初的问题似乎期望将运行时值转换为编译时值,这根本不可能。但是您可以实现一个跳转表,这样您就不必亲自编写每个排列。你应该问问自己这样做是否值得,因为最终结果将更难维护,特别是当你的团队都是初级开发者时。很多资深开发者看到这类东西也会避而远之。

哦,你不一定会看到任何性能改进。配置文件,不要假设。