这不是我第一次遇到代码内部存在依赖于外部环境的循环的情况。
例如:
bool is_sqrt;
std::cin >> is_sqrt;
for(auto &i : vector)
{
do_smth_1(i);
//...
do_smth_n(i);
if(is_sqrt)
std::cout << std::sqrt(i);
else
std::cout << i * i;
do_smth(i);
}
很明显,你可以简单地将条件移到循环之外,只需在循环中写一个替代方案即可else
:
if(is_sqrt) for(auto &i : vector)
{
do_smth_1(i);
//...
do_smth_n(i);
std::cout << std::sqrt(i);
do_smth(i);
}
else for(auto &i : vector)
{
do_smth_1(i);
//...
do_smth_n(i);
std::cout << i * i;
do_smth(i);
}
一段时间后,代码会增长,错误开始出现,因为需要复制代码(而复制本身也同样令人困惑)。我看到使用std::function
/*function
作为解决方案,但显然这两种方法在性能方面都比代码复制更差。实际上,我并不需要这种速度差异,这个问题只是出于兴趣。
如果 C++ 中没有解决这种情况的方法,也许有人在其他语言中见过这种情况?看看会很有趣。
使用模板,你可以这样做
或者
您可以创建一个指向要调用的函数的函数指针:
注意:
std::sqrt
不是可寻址函数,因此需要由可寻址函数包装它。您可以避免
std::function
使用 lambda,而直接使用,如今大多数编译器都会对其进行优化,因此最终与完全复制版本的代码应该没有区别:代码需要
<type_traits>
包含,并且为C++17if constexpr
。您可以通过 将其推广到 true/false 之外
std::integral_constant
,但您确实需要明确分派它可能具有的每个可能值。(如果您要分派的可能值数量超过一把,则扩展性不佳。)C++ 核心指南第 1 条:不要无缘无故地进行优化
原因:
至于我,我将使用
我觉得这可能会稍微快一些并且不会引入太多的复杂性。