Leo*_*ldo 5 c++ algorithm stl bind
你能解释一下这段代码是如何工作的吗?它成功地计算了具有偶数值的向量元素,但我不清楚在这种特殊情况下绑定是如何工作的。
count_if(vec.begin(), vec.end(),
std::bind(logical_not<bool>(),
std::bind(modulus<int>(), placeholders::_1, 2)));
Run Code Online (Sandbox Code Playgroud)
请注意,您发布的代码计算向量中的偶数,而不是奇数:
Run Code Online (Sandbox Code Playgroud)count_if(vec.begin(), vec.end(), bind(logical_not<bool>(), bind(modulus<int>(), placeholders::_1, 2)));
这count_if是一种返回指定范围内满足特定条件的元素数量的算法:
count_if(first, last, criteria)
Run Code Online (Sandbox Code Playgroud)
在你的情况下,firstisvec.begin()和lastis vec.end():所以整个向量被考虑用于计数。
现在让我们将注意力集中在标准部分。
从内开始,向外:
modulus<int>是一个返回整数除法余数的函数对象%(就像运算符一样)。它需要两个参数:第一个表示为placeholders::_1,它是源向量中的通用元素。将其视为x扫描整个矢量内容的变量。
第二个参数是 number 2,因为要检查整数是偶数还是奇数,您可以计算x % 2结果并将其与 0 进行比较:
x % 2 == 0 --> even number
x % 2 == 1 --> odd number
Run Code Online (Sandbox Code Playgroud)
bind用于指定modulus函数对象的参数。
此模运算的结果作为另一个函数对象的输入给出:logical_not<bool>。这只是否定输入,例如,如果输入为false(0),则logical_not<bool>返回true,反之亦然。
因此,“计数标准”由以下操作流程表示:
placeholders::_1 % 2,即<<generic vector element>> % 2,使用modulus。0(假),则返回true(反之亦然),使用logical_not.因此,如果一个数是偶数:
even number % 2 == 0true.相反,如果一个数字是奇数:
odd number % 2 == 1false.由于count_if计算条件为 的元素数量true,因此您正在计算向量中的偶数。
如果你真的想计算向量中的奇数,你可以去掉逻辑反转(即logical_not):
auto odds = count_if(vec.begin(), vec.end(),
bind(modulus<int>(), placeholders::_1, 2));
Run Code Online (Sandbox Code Playgroud)
modulus请注意,在这种情况下,使用and的函数方法logical_not似乎太复杂:使用lambda(甚至是一个临时的 IsEven() 简单函数)会更清晰。
考虑以下代码(位于 Ideone 上)来比较这三种方法:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
bool IsEven(int n) {
return (n % 2) == 0;
}
int main() {
// Test vector
vector<int> vec{ 11, 22, 33, 44, 55 };
// Using functional approach
auto n = count_if(vec.begin(), vec.end(),
bind(logical_not<bool>(),
bind(modulus<int>(), placeholders::_1, 2)));
cout << n << endl;
// Using lambdas
n = count_if(vec.begin(), vec.end(),
[](int n) { return (n % 2) == 0; });
cout << n << endl;
// Using boolean returning ad hoc function
n = count_if(vec.begin(), vec.end(), IsEven);
cout << n << endl;
}
Run Code Online (Sandbox Code Playgroud)