是否有可能使用boost :: filter_iterator输出? [英] Is it possible to use boost::filter_iterator for output?

查看:402
本文介绍了是否有可能使用boost :: filter_iterator输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的std ::变换的std :: back_inserter 追加元素添加到的std :: deque的。现在的转型可能会失败,会返回一个无效的对象(比如未初始化的的boost ::可选的或一个空指针)在某些情况下。我想从得到附加过滤掉无效的对象。

我想过使用的boost :: filter_iterator ,但不知道如何present的端()过滤的范围的参数。

的boost :: filter_iterator 的文件表明,输出滤波是可能的。如果我只是专注运算符== 的std :: back_insert_iterator 在这种情况下总是返回false?

除此之外,如果我要追加初始化的boost ::可选的值或指针,我可以链接的boost :: filter_iterator 的boost :: indirect_iterator

我试图避免推出我自己的 transform_valid 函数,它接受一个可选的提取功能。

它甚至有可能使用 filter_iterator 作为一个输出迭代器?


解决方案

我建议使用升压范围(算法和放大器;适配器)为方便使用,你会写:

 的boost ::复制(
    数据|转化(MAKET)|过滤(验证)/ * | *间接寻址/,
    的std :: back_inserter(队列));

下面就是一个完整的工作示例:

 的#include<升压/ range.hpp>
#包括LT&;升压/范围/ adaptors.hpp>
#包括LT&;升压/范围/ algorithm.hpp>
#包括LT&;升压/ optional.hpp>#包括LT&;矢量>
#包括LT&;&双端GT;TYPEDEF提振::可选< INT>笔;
的typedef的std :: deque的< T> Q;静态ŧMAKET(int i)以
{
    如果(I%2)返回T();
    否则返回我;
}静态布尔验证(常量T&安培;可选)
{
    回报(布尔)可选; //选择有一个值设置可选
}诠释的main()
{
    静态const int的数据[] = {1,2,3,4,5,6,7,8,9};    Q Q;    使用boost ::适配器::过滤;
    使用boost ::适配器::转化;    //注意如何提升范围典雅支持一个int []作为输入范围
    提高::复制(数据|转换(MAKET)|过滤(验证),性病:: back_inserter(Q));    //演示输出:2,4,6,8的印刷
    对于(Q ::常量性吧= q.begin(!);它= q.end(); ++吧)
    {
        性病::法院LT&;< (*为一套:未设置)<< \\ t的<< IT-> get_value_or(0)&所述;&下;的std :: ENDL;
    }    返回0;
}

更新

从这个答案有点帮助:<一href=\"http://stackoverflow.com/questions/6123327/use-boostoptional-together-with-boostadaptorsindirected\">Use推动::可选一起的boost ::适配器:: 间接寻址

我现在包括使用优雅的演示进行间接寻址系列适配器以及队列立即输出(取消引用自选):


  

<子>请注意,(智能)指针类型会有的显然的不需要提供指针对象&LT;&GT; 专业化。我认为这是由设计: <$c$c>optional<>不,一点也不模型,指针


 的#include&LT;升压/ range.hpp&GT;
#包括LT&;升压/范围/ adaptors.hpp&GT;
#包括LT&;升压/范围/ algorithm.hpp&GT;#包括LT&;升压/ optional.hpp&GT;名字空间boost {
    模板&LT; typename的P&GT;结构指针对象&LT;可选&LT; P&GT; &GT; {
        的typedef typename的可选&LT; P&GT; :: value_type的类型;
    };
}TYPEDEF提振::可选&LT; INT&GT;笔;静态ŧMAKET(int i)以{回报我%2? T():我; }
静态布尔验证(常量T&安培;可选){返回(布尔)可选; }诠释主(){
    使用空间boost ::适配器;    静态int数据[] = {1,2,3,4,5,6,7,8,9};
    提高::复制(数据|转换(MAKET)
                     |过滤(验证)
                     |进行间接寻址,
                     的std :: ostream_iterator&LT; INT&GT;(STD ::法院));
}

I am using std::transform with an std::back_inserter to append elements to an std::deque. Now the transformation may fail and will return a invalid object (say an uninitialized boost::optional or a null pointer) in some cases. I would like to filter out the invalid objects from getting appended.

I thought about using boost::filter_iterator, but not sure how to present the end() parameter of the filtered range.

The documentation of boost::filter_iterator suggests that output filtering is possible. Should I just specialize operator == for std::back_insert_iterator in this case to always return false?

In addition to this, if I want to append values of initialized boost::optional or pointers, can I chain boost::filter_iterator and boost::indirect_iterator?

I am trying to avoid rolling out my own transform_valid function that takes an optional extractor function.

Is it even possible to use filter_iterator as an output iterator?

解决方案

I suggest using boost range (algorithms & adaptors) for ease of use, you'd write:

boost::copy(
    data | transformed(makeT) | filtered(validate) /* | indirected */, 
    std::back_inserter(queue));

Here is a complete working example of that:

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

#include <vector>
#include <deque>

typedef boost::optional<int> T;
typedef std::deque<T> Q;

static T makeT(int i)
{
    if (i%2) return T();
    else     return i;
}

static bool validate(const T& optional) 
{ 
    return (bool) optional; // select the optional that had a value set
}

int main()
{
    static const int data[] =  { 1,2,3,4,5,6,7,8,9 };

    Q q;

    using boost::adaptors::filtered;
    using boost::adaptors::transformed;

    // note how Boost Range elegantly supports an int[] as an input range
    boost::copy(data | transformed(makeT) | filtered(validate), std::back_inserter(q));

    // demo output: 2, 4, 6, 8 printed
    for (Q::const_iterator it=q.begin(); it!=q.end(); ++it)
    {
        std::cout << (*it? "set" : "unset") << "\t" << it->get_value_or(0) << std::endl;
    }

    return 0;
}

Update

With a little help from this answer: Use boost::optional together with boost::adaptors::indirected

I now include an elegant demonstration of using the indirected range adaptor as well for immediate output of the queue (dereferencing the optionals):

Note that for (smart) pointer types there would obviously be no need to provide the pointee<> specialisation. I reckon this is by design: optional<> is not, and does not model, a pointer

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

#include <boost/optional.hpp>

namespace boost {
    template<typename P> struct pointee<optional<P> > {
        typedef typename optional<P>::value_type type;
    };
}

typedef boost::optional<int> T;

static T    makeT(int i)                { return i%2?  T() : i; }
static bool validate(const T& optional) { return (bool) optional; }

int main() {
    using namespace boost::adaptors;

    static int data[] =  { 1,2,3,4,5,6,7,8,9 };
    boost::copy(data | transformed(makeT) 
                     | filtered(validate) 
                     | indirected, 
                     std::ostream_iterator<int>(std::cout, ", "));
}

这篇关于是否有可能使用boost :: filter_iterator输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆