for_each以避免原始循环

for_each to avoid raw loop

本文关键字:原始 循环 each for      更新时间:2023-10-16

我正在尝试使用STL算法(C++11)重写一些代码,但我被困在"无原始循环"规则上。

我的一个函数中有这段代码:

for (size_t i = 0; i < cars->size(); i++) {
        if (cars->at(i).getNumber() == nr) {
               throw RepositoryException ("Product with the same number already exists");
        }
    }

汽车是矢量的类型

nr 是我作为参数得到的整数

这个 for 循环实际上只做一些有效性,整个函数做其他事情,所以我的问题是,有没有一种用一些 STL 算法替换这个循环的好方法? for_each似乎是一个尝试,但我无法弄清楚如何使用它,因为我不能真正只为这个特定的有效性制作另一个函数。

我看到了在for_each中使用lambda的方法,但我也不确定该怎么做。

谢谢

如果你使用 C++11 编译,我建议std::any_of

#include <algorithm>
//...
if (std::any_of(std::begin(*cars),std::end(*cars), 
   [&nr](const Car& c){return c.getNumber() == nr;})
{
   throw RepositoryException ("Product with the same number already exists");
}

我假设cars包含类型 Car 的对象

std::for_each(cars->begin(), cars->end(),
  [=](const Car& c) {
    if (c.getNumber() == nr) {
      throw RepositoryException("Product with the same number already exists");
    }
  }
);

但实际上,大多数时候for_each使代码比普通循环更难阅读。

对于这种情况,我还可以按find_if服务:

if (std::find_if(cars->begin(), cars->end(),
      [=](const Car& c) { return c.getNumber() == nr; })
    != cars->end()) {
  throw RepositoryException("Product with the same number already exists");
}

目前还不清楚这是否更容易阅读。

你可以

这样std::find_if

if (std::find_if(begin(*cars), end(*cars),
       [&](const auto& v) {return v.getNumber() == nr;}) != end(*cars))
  throw RepositoryException ("Product with the same number already exists");

在这种情况下,您可以使用for_each,如下所示:

std::for_each(cars.begin(), cars.end(),
  [nr](Car& c){
    if(c.getNumber() == nr)
      throw RepositoryException ("Product with the same number already exists");
  });

尽管 IMO C++11 基于范围的循环更干净:

for(auto& c : cars) {
  if(c.getNumber() == nr)
    throw RepositoryException ("Product with the same number already exists");
}

你没有说你正在为哪个版本的C++编码。 其他答案为您提供了 C++11 及更高版本的解决方案。以下是一些 C++11 之前的解决方案,以防其他人需要它们:

struct checkForProductNumber
{
    int nr;
    checkForProductNumber(int n) : nr(n) {}
    void operator()(const Car &c)
    {
        if (c.getNumber() == nr)
            throw RepositoryException ("Product with the same number already exists");
    }
}
void someClass::doSomething()
{
    //...
    std::for_each(cars->begin(), cars->end(), checkForProductNumber(nr));
    //...
}

struct hasProductNumber
{
    int nr;
    hasProductNumber(int n) : nr(n) {}
    bool operator()(const Car &c)
    {
        return (c.getNumber() == nr);
    }
}
void someClass::doSomething()
{
    //...
    if (std::find_if(cars->begin(), cars->end(), hasProductNumber(nr)) != cars->end())
    {
        throw RepositoryException ("Product with the same number already exists");
    //...
}