C++ 'std::count_'if'的二进制谓词不起作用
我目前正在尝试使用lambda函数来C++ 'std::count_'if'的二进制谓词不起作用,c++,algorithm,c++11,lambda,stdvector,C++,Algorithm,C++11,Lambda,Stdvector,我目前正在尝试使用lambda函数来std::count_,如果数组中两个连续元素的总和等于一个数字。下面给出了一个示例代码 #include <iostream> #include <vector> #include <algorithm> int main() { const int Number = 3; std::vector<int> vec = {1,1,2,4,5,6}; auto count =
std::count_,如果
数组中两个连续元素的总和等于一个数字。下面给出了一个示例代码
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
const int Number = 3;
std::vector<int> vec = {1,1,2,4,5,6};
auto count = std::count_if( vec.begin(), vec.end(),
[&](int A, int B) -> bool
{ return A+B == Number; });
std::cout << count << '\n';
}
问题是它使用一元谓词。编译器告诉你们:“你们给了我一个有两个参数的lambda,我期望lambda有一个参数”
我相信你要找的是。它比较容器的每两个相邻元素(可能使用二进制谓词)。另一个可能的选项是使用。首先,我要编写一个小助手函数:
#include <numeric>
#include <functional>
#include <iterator>
template <typename ForwardIterator, typename BinaryPredicate>
auto count_pairs_if(ForwardIterator first, ForwardIterator last,
BinaryPredicate pred)
{
const auto n = std::distance(first, last);
if (n < 2) return std::size_t {0};
return std::inner_product(first, std::next(first, n - 1), std::next(first),
std::size_t {0}, std::plus<> {}, pred);
}
template <typename Range, typename BinaryPredicate>
auto count_pairs_if(const Range& values, BinaryPredicate pred)
{
return count_pairs_if(std::cbegin(values), std::cend(values), pred);
}
这里有一个。如前所述,std::count\u if
是为一元谓词设计的。因此编译器不能接受lambda,我通过了
过了一会儿,我找到了解决这个问题的另一个办法。如果我提供一个模板函数,它需要
或者,让谓词记住前面的元素。这是不太推荐的,因为它是一个非通用的解决方案,需要非空的容器()
std::count\u如果
需要一个带有单个参数的函数。虽然相邻的\u find只找到第一对,但不计算它们。嗯,对。我不确定
中是否有任何函数可以使用二进制谓词来计算元素。可能需要外部循环来计数找到的事件。如果您定义了一个自定义迭代器来取消对一对相邻值的引用,则可以使用count\u来实现这一点:;2) 您的谓词是更深层次的无载波谓词,即它接受该对。或者甚至可以使用一个有状态谓词来记住以前的值。您可以编写一个模板函数nexture\u count
,这与std::nexture\u find
非常类似,只需在循环中运行它并返回找到的项的计数。
#include <numeric>
#include <functional>
#include <iterator>
template <typename ForwardIterator, typename BinaryPredicate>
auto count_pairs_if(ForwardIterator first, ForwardIterator last,
BinaryPredicate pred)
{
const auto n = std::distance(first, last);
if (n < 2) return std::size_t {0};
return std::inner_product(first, std::next(first, n - 1), std::next(first),
std::size_t {0}, std::plus<> {}, pred);
}
template <typename Range, typename BinaryPredicate>
auto count_pairs_if(const Range& values, BinaryPredicate pred)
{
return count_pairs_if(std::cbegin(values), std::cend(values), pred);
}
auto count = count_pairs_if(vec, [=] (auto lhs, auto rhs) { return lhs + rhs == Number; });
template <typename Iterator, typename BinaryPred = std::equal_to<>>
constexpr std::size_t count_adjacent_if(
Iterator beginIter,
const Iterator endIter,
const BinaryPred pred = {})
{
if (beginIter == endIter) return 0; // nothing to do!
std::size_t count{};
for (Iterator nextIter{ beginIter }; ++nextIter != endIter; beginIter = nextIter)
if (pred(*beginIter, *nextIter))
++count;
return count;
}
const auto count = ::count_adjacent_if(
vec.cbegin(), vec.cend(), [number](const int lhs, const int rhs) { return lhs + rhs == number; }
);
int lhs = vec[0];
const auto count = std::count_if(vec.cbegin() + 1, vec.cend(),
[&](const int rhs) {
const bool condition = (lhs + rhs == number); // check for the condition
lhs = rhs; // change the lhs = rhs (i.e. current element = next element)
return condition; // return the condition
});