c++ - 将手写循环转换为标准库调用

标签 c++ c++11 c++14

我最近看了 Sean Parent 在 2013 年关于 C++ seasoning 的演讲。如果我没有理解错的话,他说你可以从你的代码中消除几乎所有(所有?)手写循环。我的问题是如何实现这一目标? 让我们考虑以下代码:

class ProgressDialog
{
  //interesting part of that class
  void SetPosition(int position);
  bool IsCancelRequested();
  void SetHeader(const std::string& status);
}
void foo( const std::vector<std::string>& v)
{
  ProgressDialog dlg;
  long position = 0;
  for( const auto& s : v)
  {
    ++position;
    dlg.SetPosition(position);
    dlg.SetHeader("Processing"+ s);
    DoSomethingThatTakesSomeTime(s);
    if(dlg.IsCancelRequested()) break;
  }
}

有没有办法重构手写循环?

最佳答案

我不确定这是否会增加任何清晰度,但这是重构循环和提前中断概念的尝试。

#include <string>
#include <vector>
#include <ciso646>

struct ProgressDialog
{
  //interesting part of that class
  void SetPosition(int position);
  bool IsCancelRequested();
  void SetHeader(const std::string& status);
};
void DoSomethingThatTakesSomeTime(std::string const&);

// iterate over a container, calling func with the current value.
// if func returns false, cease iterating immediately.
// return true if terminated early
// note: func must return false if it wishes early termination,
// otherwise true
template<class Cont, class F> 
auto for_each_while(Cont&& container, F&& func)
{
    for(auto&& s : container)
        if (not func(s)) 
            return true;
    return false;
}

void foo( const std::vector<std::string>& v)
{
    auto update_dialog = 
    [position = 0, dlg = ProgressDialog()](auto&& s) mutable
    {
        ++position;
        dlg.SetPosition(position);
        dlg.SetHeader("Processing"+ s);
        DoSomethingThatTakesSomeTime(s);
        return !dlg.IsCancelRequested();
    };
    for_each_while(v, update_dialog);
}

这里有一些 std 库滥用实现了同样的目的。

我强烈建议您不要这样做,因为一般读者并不清楚发生了什么!

void foo( const std::vector<std::string>& v)
{
    int position = 0;
    auto dlg = ProgressDialog();

    std::find_if(begin(v), end(v), 
                 [&](auto&& s)
    {
        ++position;
        dlg.SetPosition(position);
        dlg.SetHeader("Processing"+ s);
        DoSomethingThatTakesSomeTime(s);
        return dlg.IsCancelRequested();
    });
}

关于c++ - 将手写循环转换为标准库调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52603405/

相关文章:

python - 使用 Swig 在成员中使用互斥锁包装 C++ 类时出现问题

c# - 使用指向 C# 的指针迁移函数 C++

c++ - 这个 `do..while` 循环不工作

c++ - 使用 new 运算符定义 std::shared_ptr 时出错

c++ auto type signed to/from unsigned 转换

c++ - 属性存在通用检查

c++ - 如何让 glutTimerFunct 调用子类函数

c++ - 在 C++11 中按值捕获成员变量的好方法是什么?

c++ - 如何返回一串字母数字字符(例如 1A003B3)中的最大值?

c++ - 在 TBB parallel_for 循环中获取迭代器