如何在没有2^n if语句的情况下启动包含多个布尔参数的函数模板 我有一个CUDA C++代码,它只使用性能模板,出于性能原因,这样函数只做它需要做的事情,而不是不断加载和读取布尔代数来检查它是否需要做或不做。

如何在没有2^n if语句的情况下启动包含多个布尔参数的函数模板 我有一个CUDA C++代码,它只使用性能模板,出于性能原因,这样函数只做它需要做的事情,而不是不断加载和读取布尔代数来检查它是否需要做或不做。,c++,templates,syntax,C++,Templates,Syntax,所有模板参数都是布尔值。在启动内核时,CPU检查布尔值,并启动相应的内核模板实例化,我相信这就是所谓的内核模板实例化。我知道这会使代码大小呈指数级增长,但我的问题是关于其他方面的:启动内核模板涉及2^n if语句,是否有更智能的语法 例如,如果n=2: if(bool1){ if(bool2){ <true,true>func(); } else{ <true,false>func(); } } else{

所有模板参数都是布尔值。在启动内核时,CPU检查布尔值,并启动相应的内核模板实例化,我相信这就是所谓的内核模板实例化。我知道这会使代码大小呈指数级增长,但我的问题是关于其他方面的:启动内核模板涉及2^n if语句,是否有更智能的语法

例如,如果n=2:

if(bool1){
    if(bool2){
        <true,true>func();
    }
    else{
        <true,false>func();
    }
}
else{
    if(bool2){
        <false,true>func();
    }
    else{
        <false,false>func();
    }
}
当n=10时,它就变得不可接受了,有没有一种语法可以避免这种恐怖

比如我试过 但是编译器不喜欢它


似乎在谈论一个类似的问题,但OP不仅仅有布尔值,而且提供的解决方案在我看来比问题更糟糕,坦率地说,我一个字也不懂。

将每个布尔值编码为数字中的一位,然后使用switch语句。类似这样的设置位:

int i = 0;
i = i | ((1 << (N-1)) && boolN);

您可以向func添加重载,如下所示:

template< bool... Bs >
void func()
{
    // Implement func with compile-time Bs...
}

template< bool... Bs, typename... Ts >
void func( bool b, Ts... ts )
{
    if( b ) {
        func< Bs..., true >( ts... );
    }
    else {
        func< Bs..., false >( ts... );
    }
}

int main()
{
    // call func< true, false, true, true >();
    func( true, false, true, true );
}
它的工作原理是将运行时布尔参数逐个递归地转换为编译时参数


一旦掌握了可变模板展开的诀窍,这就相当简单了

这段代码使用3个二进制编译时选项为函数的每个版本构建一个向量。向量的索引是将这些选项视为二进制位的整数值:

#include <iostream>
#include <functional>
#include <vector>

using namespace std;

// the actual function implementation 
template <bool option_a, bool option_b, bool option_c>
void function_with_options()
{
    if(option_a)
        cout << "option a is enabled, ";
    else
        cout << "no option a, ";

    if(option_b)
        cout << "option b is enabled, ";
    else
        cout << "no option b, ";

    if(option_c)
        cout << "option c is enabled, ";
    else
        cout << "no option c, ";
}


// convert an integer into the 3 option bits and return a corresponding function object 
template<int bits>
std::function<void()>
make_function_with_options()
{
    return function_with_options<bool(bits & 1), bool(bits & 2), bool(bits & 4)>;
}

// expand an index sequence of make_function_with_options<int>
template<size_t... Is>
std::vector<std::function<void()>>
make_all_functions_impl(std::index_sequence<Is...>)
{
    auto v = std::vector<std::function<void()>> { make_function_with_options<Is>()... };
    return v;
}

// make an ordered vector of the 8 function variants     
std::vector<std::function<void()>>
make_all_functions()
{
    return make_all_functions_impl(make_index_sequence<8>{});
}

// here is my global 'switch'
static const std::vector<std::function<void()>> bit_functions = make_all_functions();

int main()
{

    // call each 'switch' option to prove it works    
    for(size_t i = 0 ; i < bit_functions.size() ; ++i)
    {
        cout << "case " << i << " ";
        bit_functions[i]();
        cout << endl;
    }

    return 0;
}

或者一个映射可能比一个switch语句要好,switch语句仍然很长。你比我快了5分钟:pI还没有完全理解它,因为我以前从未见过可变模板,但我似乎已经让它与你的魔法过载一起工作了。非常短,非常优雅。最好对标志位使用无符号。公平点。也许是一个很好的转换函数,可以将布尔元组转换为索引
case 0 no option a, no option b, no option c, 
case 1 option a is enabled, no option b, no option c, 
case 2 no option a, option b is enabled, no option c, 
case 3 option a is enabled, option b is enabled, no option c, 
case 4 no option a, no option b, option c is enabled, 
case 5 option a is enabled, no option b, option c is enabled, 
case 6 no option a, option b is enabled, option c is enabled, 
case 7 option a is enabled, option b is enabled, option c is enabled,