多种模板<int>功能的专业化
Specialization of multiple template<int> functions
我运行的模拟需要使用int
参数的模板(D=系统的维度)。典型的模拟功能是
template <int D> void simulation();
当我想专门化这个模板时,我使用一个开关
switch(d){
case 2:
simulation<2>();
break;
case 3:
simulation<3>();
break;
// etc.
}
就我有一个模拟函数而言,这是可以的。但想象一下,我有10个(simul1,simul2,…simul10),d可以从2到10。我必须写十次相同的开关!
我想知道是否有可能对其进行因子分解,并得到类似的东西:
template <void (*fun)()> runSimulation(int d){
switch(d){
case 2:
fun<2>();
}
}
当然,<void (*fun)()>
不能做我想做的事,因为fun
是template<int>
。有办法做到吗?
当您可以将模拟函数更改为具有静态方法的类时:
struct sim1
{
template<int D> static void apply();
};
然后以下内容应该起作用:
template <typename Sim> runSimulation(int d){
switch(d){
case 2:
Sim::template apply<2>();
case 3:
Sim::template apply<3>();
// ...
}
}
它是通用的,可以用runSimulation<sim1>(d);
或runSimulation<sim2>(d);
等调用。
以下是一个使用模板递归将运行时信息转换为编译时信息的简单方案:
template<int N> void runSimulation() { std::cout<<"runSimulation " << N << std::endl; }
constexpr size_t max_index = 100;
namespace detail
{
//overload for maximum index
void callSimulation_impl(size_t i, std::integral_constant<size_t, max_index>) {}
template<size_t N>
void callSimulation_impl(size_t i, std::integral_constant<size_t, N>)
{
if(i==N)
{
runSimulation<N>();
}
else
{
callSimulation_impl(i, std::integral_constant<size_t, N+1>());
}
}
}
void callSimulation(size_t i)
{
detail::callSimulation_impl(i, std::integral_constant<size_t, 0>());
}
int main(int argc, char *argv[])
{
callSimulation(10); // calls runSimulation<10>();
//or also:
callSimulation(rand()%max_index); //calls a random simulation
}
演示
就像您生成的手动切换一样,它需要传递索引大小的线性努力(使用二进制搜索也可以实现类似的算法)。
如果效率很重要,你也可以通过使用魔术开关来实现O(1)
,看看这里和这里——我是它的忠实粉丝
编辑:此方案可以与@Daniel Frey的另一个答案相结合,以便为多种模拟类型和任意多个切换情况获得单个函数。
如果C++接受模板函数作为模板参数,那就太好了,但我不知道如何表达。但是,它接受模板类作为模板参数。
如果您愿意将模拟系列(simul1、simul2等)打包到每个系列(Wrapper1、Wrapper2等)的一个包装器模板中,您可以执行以下操作:
template<template<int D> class SimulationFunctionWrapper> struct Caller {
static void simulation(int d) {
switch(d) {
case 2: SimulationFunctionWrapper<2>::run(); break;
case 3: SimulationFunctionWrapper<3>::run(); break;
}
}
};
#include <iostream>
// normal simul1 declarations and definitions
template<int D> void simul1();
template<> void simul1<2>() { std::cout << "simul1<2>n"; }
template<> void simul1<3>() { std::cout << "simul1<3>n"; }
// Enables dispatching to the right simul1 based on the template integer
template<int D> struct Wrapper1 { static void run() { simul1<D>(); } };
// normal simul2 declarations and definitions
template<int D> void simul2();
template<> void simul2<2>() { std::cout << "simul2<2>n"; }
template<> void simul2<3>() { std::cout << "simul2<3>n"; }
// Enables dispatching to the right simul2 based on the template integer
template<int D> struct Wrapper2 { static void run() { simul2<D>(); } };
int main(int argc, const char *argv[]) {
Caller<Wrapper1>::simulation(argc);
Caller<Wrapper2>::simulation(argc);
return 0;
}
这显示了如何使用相同的代码(Caller
)来决定调用哪个单独的函数。不幸的是,它需要样板包装。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- EASTL矢量<向量<int>>连续的
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 询问在设计我的手臂模拟器功能表示格式1
- 功能原型的目的