我希望将函数UnaryFunction f
应用于std容器的某些元素,给定谓词UnaryPredicate p
- 如果将std::partition
和std::for_each
结合使用,将会得到什么然后将cppreference.com应用于其中一个分区。
我对C ++很陌生,所以请原谅我的无知。但是,我在<algorithm>
中寻找了一个合适的实现,但我似乎无法找到所需的功能。
根据OutputIter
的可能实施情况,我提出了以下建议:
template<class InputIt, class UnaryPredicate, class UnaryFunction>
UnaryFunction for_each_if(InputIt first, InputIt last, UnaryPredicate p, UnaryFunction f)
{
for (; first != last; ++first) {
if (p(*first))
{
f(*first);
}
}
return f;
}
返回值按照std::for_each
建模,但{{3}}可能是更好的选择。这需要更复杂的实施,所以这次我选择了简洁而精致。替代实施留给读者练习。
我的问题是:在std库中已经有一种既定的方法吗?如果没有,这是否是这种功能模板的合理实现?
答案 0 :(得分:4)
STL不能很好地支持算法的组合。如您所说,如果您不关心元素的顺序,可以先调用partition
,然后在其中一个分区上调用for_each
。
对于新项目或可以引入库的项目,我强烈建议您查看范围库,例如: Boost.Range或Eric Niebler's range-v3。
使用范围库,可以这样做:
template<typename R, typename P, typename F>
F for_each_if(R& rng, P pred, F f)
{
using namespace boost::adaptors;
return (rng | filtered(pred) | for_each(f));
}
答案 1 :(得分:1)
就评论而言,似乎没有在std库中实现这一点。然而,正如user2672165指出的那样,谓词可以容易地包括在函数中。为了说明这一点,请参阅for_each
example over at cppreference.com的以下修改版本:
#include <vector>
#include <algorithm>
#include <iostream>
struct Sum {
Sum() { sum = 0; }
void operator()(int n) { sum += n; }
int sum;
};
int main()
{
std::vector<int> nums{3, 4, 2, 9, 15, 267};
std::cout << "before: ";
for (auto n : nums) {
std::cout << n << " ";
}
std::cout << '\n';
std::for_each(nums.begin(), nums.end(), [](int &n){ if (n > 5) n++; });
// Calls Sum::operator() for each number
Sum s = std::for_each(nums.begin(), nums.end(), Sum());
std::cout << "after: ";
for (auto n : nums) {
std::cout << n << " ";
}
std::cout << '\n';
std::cout << "sum: " << s.sum << '\n';
}
这里,谓词被添加到函数中,因此[](int &n){ n++; }
现在变为[](int &n){ if (n > 5) n++; }
,仅将函数应用于大于5的整数元素。
预期输出
before: 3 4 2 9 15 267
after: 3 4 2 10 16 268
sum: 303
希望这有助于其他人。