处理2+模板参数的最佳方法是什么?

apo*_*apo 3 c++ templates

假设我有以下形式的模板化函数:

template<bool a, bool b, bool c>
void foo(){
   if(a) printf("I do something when a is true!\n");
   if(b) printf("I do something when b is true!\n");
   if(c) printf("I do something when c is true!\n");
}
Run Code Online (Sandbox Code Playgroud)

现在我有这个函数可以编译时间专门针对8种可能情况中的每一种情况(a = b = c = true,a = b = true c = false等等).

我想在运行时获得的a,b和c值调用此函数.

如果模板只有一个参数我可以做:

void caller(bool a){
   if(a) foo<true>();
   else  foo<false>();
}
Run Code Online (Sandbox Code Playgroud)

但是,如果你有2个以上的参数怎么办?你不能只做:

void caller(bool a, bool b, bool c){
   foo<a,b,c>();
}
Run Code Online (Sandbox Code Playgroud)

如果你使用if-else/switch进行这种麻烦的疯狂是不可取的.我想让编译器编译foo的8个版本并且只是调用

foo<a,b,c>()
Run Code Online (Sandbox Code Playgroud)

如果相反bool,我可以做同样的情况:

template<int a>
void foo(){
   printf("%d", a);
} 
Run Code Online (Sandbox Code Playgroud)

假设我知道a可以在0和32之间变化,即32.我想做类似的事情:

void caller(int a){
   if(a<=32 && a>0) foo<a>();
   else printf("ERROR!/n");
}
Run Code Online (Sandbox Code Playgroud)

处理这类情况的最佳方法是什么?

Vit*_*meo 5

但是,如果你有2个以上的参数怎么办?你不能只做:

您可以使用可变参数模板,递归,高阶函数和std::integral_constant:

template <typename TF>
auto with_bool_constant(TF xf)
{
    return xf();
};

template <typename TF, typename T, typename... Ts>
auto with_bool_constant(TF xf, T x, Ts... xs)
{
    if(x) 
        return with_bool_constant([&](auto... ys)
                                  { xf(std::integral_constant<bool, true>{}, ys...); }, 
                                  xs...);
    else 
        return with_bool_constant([&](auto... ys)
                                  { xf(std::integral_constant<bool, false>{}, ys...); }, 
                                  xs...);
};
Run Code Online (Sandbox Code Playgroud)

用法:

template <bool a, bool b, bool c>
void f() 
{ 
    std::cout << std::boolalpha << a << " " << b << " " << c << "\n"; 
}

int main()
{
    auto f_wrapper = [](auto a, auto b, auto c)
    {
        return f<a, b, c>();
    };

    with_bool_constant(f_wrapper, true, false, true);
}
Run Code Online (Sandbox Code Playgroud)

wandbox示例


假设我知道a可以在0和32之间变化,即32.我想做类似的事情:

您可以使用它boost::hana::make_range来生成0...32编译时范围(必须在编译时知道边界).然后,您可以使用boost::hana::for_each或类似的编译时迭代构造将运行时值转换为std::integral_constant<int, X>并将类似的技术应用于上面发布的那个.