假设我有以下形式的模板化函数:
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)
处理这类情况的最佳方法是什么?
但是,如果你有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)
假设我知道a可以在0和32之间变化,即32.我想做类似的事情:
您可以使用它boost::hana::make_range来生成0...32编译时范围(必须在编译时知道边界).然后,您可以使用boost::hana::for_each或类似的编译时迭代构造将运行时值转换为std::integral_constant<int, X>并将类似的技术应用于上面发布的那个.
| 归档时间: |
|
| 查看次数: |
154 次 |
| 最近记录: |