stl中是不是有类似execute_if算法的东西?

Posted

技术标签:

【中文标题】stl中是不是有类似execute_if算法的东西?【英文标题】:Is there anything like an execute_if algorithm in stl?stl中是否有类似execute_if算法的东西? 【发布时间】:2020-09-15 10:55:50 【问题描述】:

就像 STL 中有 count_if 和 remove_if 算法一样,我想找到类似 execute_if 的东西,它将条件谓词与函数分开执行。

例如,我想要 1 行使用 2 个 lambda 打印所有赔率,如下所示:

auto vec = vector<int> 1,2,3,4,5 ;
for_each_if(vec.begin(), vec.end(), [](auto val) return val % 2 != 0; , [](auto val)  cout << val; );

用算法来做这件事的好方法是什么?

【问题讨论】:

今天为什么会有这样的算法?仿函数实际上可以做任何事情,并且使用 lambdas 我们可以轻松地组合现有的仿函数。 std::for_each 和 lambda 包含一个 if?这比你的提议要清楚得多。 execute_if 函数与普通的if 语句有何不同? 关注点分离。例如:一个调用者会发送 ifodds,另一个调用者会发送 ifevens。两者都会发送打印机。或者一个来电者发送了一个数字打印机,另一个人发送了其他东西。两者都会发送 ifodds。 为什么需要两个 lambda?从 C++11 开始,std::copy_if(vec.begin(), vec.end(), std::ostream_iterator(std::cout, " "), [](auto val) return val %2 != 0;) 将按照您的要求进行操作(假设您希望输出值之间有空格)。 【参考方案1】:

如果你有 C++20 支持,你可以使用新的range-library:

std::vector<int> vec 1,2,3,4,5 ;
for (auto val : vec | std::views::filter([](auto val)  return val % 2 != 0; ))

    std::cout << val;

或者(当然):

std::vector<int> vec 1,2,3,4,5 ;
auto filtered = vec | std::views::filter([](auto val) return val % 2 != 0; );
std::for_each(filtered.begin(), filtered.end(), [](auto val)  std::cout << val;  );

Live Demo

【讨论】:

【参考方案2】:

您可以自己编写这样的算法:

#include <iostream>
#include <algorithm>
#include <vector>


template <typename IT,typename predicate,typename func>
void for_each_if(IT begin,IT end,predicate p, func f)
    std::for_each(begin,end,[&f,&p](auto val)
        if (p(val)) f(val);
    );



int main() 
    auto vec = std::vector<int> 1,2,3,4,5 ;
    for_each_if(vec.begin(), vec.end(), [](auto val) return val % 2 != 0; , [](auto val)  std::cout << val; );

但是,请准备好进行一场实际上更具可读性的辩论。我绝对更喜欢只将一个函子传递给for_each,而不是将两个函子传递给for_each_if

关注点分离。一个调用者会发送 ifodds,另一个调用者会发送 ifevens。两者都会发送打印机。

您不需要额外的算法。上面的替代方案是:

auto condition = [](auto val) return val % 2 != 0; ;
auto func = [](auto val)  std::cout << val; ;
auto if_fun = [&condition,&func](auto val) if (condition(val)) func(val);;
std::for_each(vec.begin(),vec.end(),if_fun);

您可以根据需要从不同的谓词和不同的函数组合if_fun

【讨论】:

这是一个方便和清晰的问题。那么按照你的逻辑,我们不需要count_if。我可以自己做一个 foreach 并计算比赛。 @GonenI 使用标准算法的原因是可读性和表达性,但这种优势主要源于它们是标准的事实。您可以发明您认为具有超级可读性的最佳算法,但很难与大家都知道的标准算法竞争,文档无处不在,并且经过数百万用户的测试和调试 @GonenI 无论如何我并不是要暗示这个“按照你的逻辑,我们不需要 count_if。”如果您在答案中读到此内容,那么也许我解释得不够好

以上是关于stl中是不是有类似execute_if算法的东西?的主要内容,如果未能解决你的问题,请参考以下文章

STL——配接器常用算法使用

STL初识

STL x

STL 算法中函数对象和谓词

STL 常用方法

STL算法中函数对象和谓词