gpt4 book ai didi

c++ - 模拟条件 back_inserter 之类的最佳方法?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:40:58 26 4
gpt4 key购买 nike

我想用以下代码中的算法替换循环

int numbers[] = { ... };
vector<int> output;

for( int* it = numbers+from; it != numbers+to ; ++it )
{
int square = func( *it );
if( predicate(square) )
{
output.push_back(square);
}
}

该程序旨在转换值并在条件发生时将它们复制到目的地。

  • 我无法使用 std::copy_if,因为那样不会应用转换。
  • 我无法使用 std::transform 因为它缺少谓词
  • 因为转换变量的中间拷贝,编写 transform_copy_if() 甚至不是一个好主意。

看来我唯一的希望是创建一个conditional_back_insert_iterator。然后我可以像这样打一个相当不错的电话:

int numbers[] = { ... };
vector<int> output;

std::transform(numbers+from, numbers+to,
conditional_back_inserter(predicate, output),
func);

这个解决方案是处理此类情况的最佳方法吗?我什至无法通过谷歌搜索条件插入器,所以我担心我走错了路。

我也可以想象我可以实现替代解决方案,例如

std::copy_if( transform_iterator<func>(numbers+from), 
transform_iterator<func>(numbers+to),
back_inserter(output) );

(这让我想起了 boost 中 *filter_iterators* 的例子)但这不提供可读性。

最佳答案

我认为创建自己的迭代器是可行的方法:

#include <iostream>
#include <vector>
#include <iterator>
#include <functional>

template<class T>
class conditional_back_insert_iterator
: public std::back_insert_iterator<std::vector<T>>
{
private:
using Base = std::back_insert_iterator<std::vector<T>>;
using Container = std::vector<T>;
using value_type = typename Container::value_type;
public:
template<class F>
conditional_back_insert_iterator(Container& other, F&& pred)
: Base(other), c(other), predicate(std::forward<F>(pred))
{ }

conditional_back_insert_iterator<T>& operator*()
{ return *this; }

conditional_back_insert_iterator<T>&
operator=(const value_type& val) const
{
if (predicate(val))
c.push_back(val);
return *this;
}

conditional_back_insert_iterator<T>&
operator=(value_type&& val) const
{
if (predicate(val))
c.push_back(std::move(val));
return *this;
}
private:
Container& c;
std::function<bool (const value_type&)> predicate;
};

template<
class Container,
class F,
class value_type = typename Container::value_type
>
conditional_back_insert_iterator<value_type>
conditional_back_inserter(Container& c, F&& predicate)
{
return conditional_back_insert_iterator<value_type>(c, std::forward<F>(predicate));
}

int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> to;

auto is_even = [] (int x) { return (x % 2) == 0; };

std::copy(v.begin(), v.end(), conditional_back_inserter(to, is_even));
}

关于c++ - 模拟条件 back_inserter 之类的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20120763/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com