我有以下带有相当大的switch语句的C++代码(我使用的是C++11编译器):
void function(std::size_t i, other_args)
{
switch(i)
{
case 0:
templatedfunction<0>(other_args);
break;
case 1:
templatedfunction<1>(other_args);
break;
case 2:
templatedfunction<2>(other_args);
break;
...............
//lots of other cases here
...............
case 100:
templatedfunction<100>(other_args);
break;
}
}其中templatedfunction定义为
template<std::size_t T>
void templatedfunction(other_args){
//some code here
}这是用于描述一个简单概念的大量代码行(即,使用与在其模板参数中传递的变量i相同的值调用templatedfunction )。在C++中有没有一种方法可以更紧凑地编写这段代码?应该有一种方法来实现这个长的switch语句,因为i是一个变量,而不是一个编译时间常数,所以compactly....Using templatedfunction<i>(other_args)将不会被编译。谢谢。
发布于 2018-10-27 17:55:43
我喜欢Evg的解决方案(+1),但是是线性的,做了很多模板递归,可以超过递归限制(也许优化器可以避免这种情况,但我不喜欢依赖优化器)。
因此,我提出了Evg解决方案的对数变体:我们可以不在单个索引上迭代,而是在表示索引间隔的几个索引上迭代。我们可以根据i的值将这个区间一分为二。
我的意思是:给定以下function()
void function (std::size_t i)
{
if ( i > 100 )
std::cout << i << " is out of range" << std::endl;
else
function_impl<0, 101>(i); // as a switch from 0 to 100 (included)
}我们可以按如下方式编写function_impl()函数
template <std::size_t L1, std::size_t L2>
void function_impl (std::size_t i)
{
if ( L1 == i )
templatedFunction<L1>();
else
{
constexpr auto LM { (L1 + L2) >> 1 };
if ( i < LM )
function_impl<L1, LM>(i);
else
function_impl<LM, L2>(i);
}
}这大大减少了递归调用的数量。
下面是一个完整的编译示例
#include <iostream>
template <std::size_t I>
void templatedFunction ()
{ std::cout << I << std::endl; }
template <std::size_t L1, std::size_t L2>
void function_impl (std::size_t i)
{
if ( L1 == i )
templatedFunction<L1>();
else
{
constexpr auto LM { (L1 + L2) >> 1 };
if ( i < LM )
function_impl<L1, LM>(i);
else
function_impl<LM, L2>(i);
}
}
void function (std::size_t i)
{
if ( i > 100 )
std::cout << i << " is out of range" << std::endl;
else
function_impl<0, 101>(i);
}
int main ()
{
for ( auto ui = 0u ; ui < 102u ; ++ui )
function(ui);
}https://stackoverflow.com/questions/53019091
复制相似问题