c++ - 避免在 C++ 中的循环中的每一步都检查相同的条件

标签 c++ for-loop coding-style conditional-statements

我正在检查循环内的条件,如果条件成立,则执行某项操作。

for (i = 0; i < n; i++)
{
    // do lots of work here
    .
    .
    .
    if (constant_condition)
        do_something(n);
}

条件是独立于n的,所以每次都检查它感觉很多余。我可以改为这样做:

if (constant_condition)
    for (i = 0; i < n; i++)
    {
        // do lots of work here
        .
        .
        .

        do_something(n);
    }
else
    for (i = 0; i < n; i++)
    {
        // do lots of work here
        .
        .
        .    
    }

这个新代码效率更高,但我不得不在我的程序中复制粘贴相同的代码。有没有一种有效的方法可以做到这一点而无需重复相同的代码块?

编辑:条件在编译时未知,但会在运行时给出并且不会改变。

最佳答案

首先,配置文件以查看它是否重要。如果是,您有多种选择:

  • 如果编译器尚未缓存常量,则在循环外缓存常量。这是最简单的,在大多数情况下就足够了:

    const bool constant_condition = ...;
    for (...) {
       ...
       if (constant_condition) do_something(...);
    }
    
  • 如果您真的需要避免分支,典型的方法是定义辅助函数或本地 lambda (C++11) 来提取公共(public)代码块。然而,这仍然是重复代码,并且根据情况,可能看起来一点也不漂亮:

    auto main_work = [...](...) { ... };
    if (constant_condition)
        for (...) { main_work(...); }
    else
        for (...) { main_work(...); do_something(...); }
    
  • 根据需要定义模板和参数化。编译器通常会适当优化,因此您只需复制粘贴代码即可。如果你真的想确保分支被删除,你可以强制它专门化模板,或者利用 if constexpr (C++17) 等。但是,要注意代码膨胀和编译时间。

    template <bool constant_condition>
    void f(...) { ... }
    
    if (constant_condition)
        f<true>(...);
    else
        f<false>(...);
    

最后,别忘了再次剖析。有时,删除分支可能看起来不错,但总体上是有害的。如果代码更改很多并且最初看起来像是一小段指令重复现在是几个充满重复代码的内存页面,则尤其如此。

另一种选择是尝试查看算法/代码是否可以改为无分支编写;但是,这不是通用的解决方案。

关于c++ - 避免在 C++ 中的循环中的每一步都检查相同的条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56742898/

相关文章:

c++ - 以旧方式迭代 C++ 中的对象指针数组(没有基于范围的 for)?

python - Django 中的设置命名空间

java - for each 循环无法初始化数组中的对象

r - 如何优化我的代码以便不使用循环

python - 每个循环仅打印一次错误消息

eclipse - 如何更改 Eclipse 自动生成代码的缩进样式?

javascript - 我应该将上传功能放在Vue组件中的哪里?

C++模板类型和模板类型

c++ - QT解析CSV文件的内容并存储到结构数组中

C++ delete[] 运算符