模仿conditional_back_inserter这样的东西的最佳方式
Best way to emulate something like conditional_back_inserter?
我想在下面的代码中用算法替换循环
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));
}
这是我的尝试。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
template <class Container, class Pred>
class conditional_insert_iterator
: public std::iterator< std::output_iterator_tag, void, void, void, void >
{
public:
explicit conditional_insert_iterator(Container& c, Pred p) : container(&c), pred(p) {}
conditional_insert_iterator& operator=(typename Container::const_reference value) {
if (pred(value))
container->push_back(value);
return *this;
}
conditional_insert_iterator& operator*() {return *this;}
conditional_insert_iterator& operator++() {return *this;}
conditional_insert_iterator& operator++(int) {return *this;}
private:
Container* container;
Pred pred;
};
template< class Container, class Pred>
conditional_insert_iterator<Container, Pred> conditional_inserter( Container& c, Pred pred )
{
return conditional_insert_iterator<Container, Pred>(c, pred);
}
using namespace std;
int main()
{
vector<int> in = { 1, 2, 3, 4, 5, 6 };
vector<int> out;
transform(in.begin(), in.end(),
conditional_inserter(out, [](int i) { return i%2 == 0;}),
[](int i) { return i + 2;});
for (auto i : out)
cout << i << "n";
return 0;
}
相关文章:
- 在c代码之间共享数据的最佳方式
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 在reactor中存储eventHandlers的最佳方式是什么
- 在AVX通道中混洗的最佳方式
- 从 T 创建 std::future 的最佳方式<T>
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- 对列表列表中的元素进行分组的最佳方式
- 利用 GPU 的最佳方式
- 使用 QT C++过滤大数据的最佳方式
- 算法设计:用边界数字表示 2D 网格的最佳方式,以C++?
- 在C++中共享键值对的最佳方式
- 为Catch2中的外部文本文件指定路径的最佳方式
- 代表Quarto棋盘游戏棋子的最佳方式
- 等待线程的最佳方式是什么
- 将uint8_t*buffer和size_tbufferlen从C++传递到C中的API函数的最佳方式是什么
- 创建控制台菜单C++的最佳方式
- 只显示片段着色器的最佳方式是什么
- 复制文件的最佳方式是什么,以便我可以在复制过程中轻松取消复制?