c – 如何组合std :: copy_if和std :: transform?

考虑此代码片段:迭代第一类型T1的一个容器,用于创建应用转换函数T1-> T2的第二类型T2的第二容器,但仅用于验证谓词的T1元素(T1 – > bool)

(在下面的例子中是奇数).

std::vector<int> myIntVector;
myIntVector.push_back(10);
myIntVector.push_back(15);
myIntVector.push_back(30);
myIntVector.push_back(13);

std::vector<std::string> myStringVectorOfOdd;

std::for_each(myIntVector.begin(),myIntVector.end(),[&myStringVectorOfOdd](int val)
{
    if (val % 2 != 0)
        myStringVectorOfOdd.push_back(std::to_string(val));

});

在这代码中不喜欢的是lambda上的捕获.有没有办法结合std :: copy_if和std :: transform以更优雅和简洁的方式实现相同的结果?

解决方法

这是一个transform_if模板,它接受通常的输入迭代器对,输出迭代器和谓词以及转换函数对象.

template <class InputIt,class OutputIt,class Pred,class Fct>
void transform_if(InputIt first,InputIt last,OutputIt dest,Pred pred,Fct transform)
{
   while (first != last) {
      if (pred(*first))
         *dest++ = transform(*first);

      ++first;
   }
}

您可以将它用于您的示例,如下所示.

transform_if(myIntVector.cbegin(),myIntVector.cend(),std::back_inserter(myStringVectorOfOdd),[](int n){ return n % 2 != 0; },[](int n){ return std::to_string(n); });

它不是超级简洁,但过滤和转换很好地分为无捕获的lambdas,算法本身惯用于迭代器.

由于范围库为编写算法提供了更好的支持,因此基于Boost range是相同的:

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

using boost::adaptors::filtered;

boost::transform(myIntVector | filtered([](int n){ return n % 2 != 0; }),[](int n){ return std::to_string(n); });

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...