处理 2+ 模板参数的最佳方法
Best way to handle 2+ template parameters?
假设我有一个以下形式的模板化函数:
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");
}
现在我有了这个函数,它可以专门针对 8 种可能情况中的每一种进行编译(a = b = c = true,a=b = true c=false 等)。
我想用运行时获得的 a、b 和 c 值调用这个函数。
如果模板只有一个参数,我可以做:
void caller(bool a){
if(a) foo<true>();
else foo<false>();
}
但是,如果您有 2+ 个参数怎么办?你不能只做:
void caller(bool a, bool b, bool c){
foo<a,b,c>();
}
如果你用if-else/switch来做,那种随意的疯狂是不可取的。我想让编译器编译 foo 的 8 个版本,然后调用
foo<a,b,c>()
如果相反,我可以做出类似的情况,我有:
template<int a>
void foo(){
printf("%d", a);
}
假设我知道 a 可以在 0 和 32 之间变化。我想做这样的事情:
void caller(int a){
if(a<=32 && a>0) foo<a>();
else printf("ERROR!/n");
}
处理这种情况的最佳方法是什么?
但是,如果您有 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...);
};
用法:
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);
}
魔杖盒示例
假设我知道 a 可以在 0 和 32 之间变化。我想做这样的事情:
可以使用boost::hana::make_range
生成0...32
编译时范围(必须在编译时知道边界)。然后,您可以使用boost::hana::for_each
或类似的编译时迭代构造将运行时值转换为std::integral_constant<int, X>
,并将类似的技术应用于我上面发布的技术。
你有正确的想法,你只需要对每个参数准递归地这样做:
#include <cstdio>
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");
}
template <bool... bs>
void caller() {
foo<bs...>();
}
template <bool... cbs, typename... RBS>
void caller(bool rb0, RBS... rbs) {
if (rb0) {
caller<cbs..., true>(rbs...);
} else {
caller<cbs..., false>(rbs...);
}
}
int main() {
caller(true, false, true);
}
相关文章:
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 检测win32服务创建和删除的最佳方法
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将线程中的数据存储到全局容器的最佳方法?
- 将一系列整数放入类的最佳方法是什么?
- 在派生类中使用基类的私有成员变量的最佳方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 将 pybind11 绑定标记为已弃用的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?