[英]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.