簡體   English   中英

將 STL 函數與結構一起使用?

[英]Using STL functions with a struct?

我最近閱讀了 C++ 中的 STL 函數。 我了解函數的基本用法,但我很難讓它們使用結構的成員變量。

我有這個結構:

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

基本上,我將Apples插入一個存儲隨機權重和隨機顏色的vector 現在,我想使用count_if函數來確定有多少蘋果大於給定的重量。 我想轉換這樣的函數:

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

count_if()版本(這不起作用):

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

isGreater()是這樣的:

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

我對 STL 函數和struct不了解的是如何將結構內部的成員變量與 STL 函數一起使用。 我也不確定要在 STL 函數內部傳遞什么。 在這種情況下使用 lambda 函數會更好嗎? 如果是這樣,為什么?

這是所有當前代碼,如果它沒有意義:

#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++; 

您沒有將蘋果存儲在向量中。 您必須在每個蘋果的循環內初始化,然后將它們存儲在向量中。 crate.push_back(newApple)。 所以運行一個從 0 到 size 的循環。 在該循環內初始化新蘋果並賦予它們權重和顏色,然后在向量中 push_back:

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

這通常是通過創建一個“函子”類來實現的,該類的對象可以像函數一樣被調用。 每個實例調用都持有參考權重:

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

然后我們只需要創建一個持有引用權重的類的實例並將其傳遞給count_if

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

您可以避免使用 lambda 創建顯式類:

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

這里toFind的引用值是按值捕獲的。

std::count_if將一元謂詞作為第三個參數。 在這種情況下,一元謂詞是一個函數,它接受一個對象,如果對象匹配查找標准則返回true否則返回false

由於您的標准取決於toFind ,因此使用 lambda 捕獲toFind似乎更簡潔:

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

如果你想要一個獨立的功能,你可以使用:

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));

請注意,您不需要調用函數,您需要傳遞它:

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