简体   繁体   English

将 STL 函数与结构一起使用?

[英]Using STL functions with a struct?

I've recently read up on STL functions in C++.我最近阅读了 C++ 中的 STL 函数。 I understand the basic uses of the functions, but I am struggling getting them to use member variables of a struct.我了解函数的基本用法,但我很难让它们使用结构的成员变量。

I have this struct:我有这个结构:

struct Apples
{
   double weight; // oz
   string color;  // red or green
   void print() const { cout << color << ", " <<  weight << endl; }
};

Basically, I insert Apples into a vector storing random weights and random color.基本上,我将Apples插入一个存储随机权重和随机颜色的vector Now, I want to use a count_if function to determine how many apples are greater than a given weight.现在,我想使用count_if函数来确定有多少苹果大于给定的重量。 I want to convert a function like this:我想转换这样的函数:

int cnt = 0;
for(auto it = crate.cbegin(); it != crate.cend(); ++it) 
    if(it->weight > toFind) 
        cnt++;

to a count_if() version (this does not work):count_if()版本(这不起作用):

int cnt = count_if(crate.begin(), crate,end(), isGreater())

With isGreater() being like this: isGreater()是这样的:

void isGreater()
{
   if(it->weight > toFind) 
      return it->weight > toFind;
}

What I don't understand about STL functions and a struct is how to use the member variables inside of the struct with the STL functions.我对 STL 函数和struct不了解的是如何将结构内部的成员变量与 STL 函数一起使用。 I'm not sure what to pass inside of the STL function, either.我也不确定要在 STL 函数内部传递什么。 Would it be better to use a lambda function in this case?在这种情况下使用 lambda 函数会更好吗? If so, why?如果是这样,为什么?

Here is all the current code, if it doesn't make sense:这是所有当前代码,如果它没有意义:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <deque>
#include <string>


using namespace std;

struct Apples
{
   double weight; // oz
   string color;  // red or green
   void print() const { cout << color << ", " <<  weight << endl; }
};

void isGreater()
{
   if(it->weight > toFind) 
      return it->weight > toFind;
}

int main()
{
   srand(time(nullptr));
   const double minWeight = 8.;
   const double maxWeight = 3.;

   cout << "Input crate size: ";
   int size;
   cin >> size;

   vector <Apples> crate(size);
   for(auto it = crate.begin(); it != crate.end(); ++it)
   {
      it->weight = minWeight + static_cast<double>(rand())/RAND_MAX*(maxWeight - minWeight);
      it->color = rand() % 2 == 1 ? "green" : "red";
   }

   cout << "Enter weight to find: ";
   double toFind;
   cin >> toFind;

  //this is what I want to convert to count if
   int cnt = 0;
   for(auto it = crate.cbegin(); it != crate.cend(); ++it) 
      if(it->weight > toFind) 
         cnt++; 

you are not storing the apples in the vector.您没有将苹果存储在向量中。 you have to initialize inside a loop each apple and then store them in the vector.您必须在每个苹果的循环内初始化,然后将它们存储在向量中。 crate.push_back(newApple). crate.push_back(newApple)。 so run a loop from 0 to size.所以运行一个从 0 到 size 的循环。 inside that loop initialize new apples and give them weights and colors then push_back in vector:在该循环内初始化新苹果并赋予它们权重和颜色,然后在向量中 push_back:

for(int i = 0; i < size ++i)
 { 
   apples newApple;
   newApple.weight = ...;
   newApple.color = ...;
   crate.push_back(newApple);
 }

This is usually accomplished by creating a "functor" class, a class whose objects can be called like a function.这通常是通过创建一个“函子”类来实现的,该类的对象可以像函数一样被调用。 Each instance call hold the reference weight:每个实例调用都持有参考权重:

struct IsGreater {
    double w;
    IsGreater(double weight) : w{weight} {}
    bool operator()(const Apples& A) const {
         return A.weight > w;
    }
};

Then we just need to create an instance of the class holding the reference weight and pass it to count_if :然后我们只需要创建一个持有引用权重的类的实例并将其传递给count_if

const int count = std::count_if(crate.begin(), crate.end(), IsGreater(toFind));

You can avoid creating an explicit class using a lambda:您可以避免使用 lambda 创建显式类:

const int count = std::count_if(crate.begin(), crate.end(),
                               [=](const Apples& A) -> bool {
                                    return A.weight > toFind;
                               });

Here the reference value toFind is captured by value.这里toFind的引用值是按值捕获的。

std::count_if takes unary predicate as the third argument. std::count_if将一元谓词作为第三个参数。 In this case unary predicate is a function taking one object and returning true if object matches find criterion or false if not.在这种情况下,一元谓词是一个函数,它接受一个对象,如果对象匹配查找标准则返回true否则返回false

Since your criterion depends on toFind , it seems more laconic to use lambda capturing toFind :由于您的标准取决于toFind ,因此使用 lambda 捕获toFind似乎更简洁:

int cnt = count_if(crate.begin(), crate.end(), [toFind](const Apple& apple) {
  return it->weight > toFind;
});

If you want a standalone function, you can use:如果你想要一个独立的功能,你可以使用:

bool isGreater(double toFind, const Apple& apple) {
   return it->weight > toFind;
}

...

int cnt = count_if(crate.begin(), crate.end(),
        std::bind(&isGreater, toFind, std::placeholders::_1));

Note, that you don't need to call function, you need to pass it:请注意,您不需要调用函数,您需要传递它:

int cnt = count_if(crate.begin(), crate,end(), isGreater())
//                                                      ^^ remove parentheses

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM