是否可以使用boost :: filter_iterator进行输出?

zrb*_*zrb 7 c++ boost stl

我正在使用std::transforman std::back_inserter来追加元素std::deque.现在转换可能会失败,并且boost::optional在某些情况下将返回无效对象(比如未初始化或空指针).我想过滤掉附加的无效对象.

我想过使用boost::filter_iterator,但不知道如何呈现end()过滤范围的参数.

文档boost::filter_iterator建议输出过滤是可能的.如果我只是专注operator ==std::back_insert_iterator在这种情况下总是返回false?

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

我试图避免推出我自己的transform_valid带有可选extractor功能的函数.

甚至可以filter_iterator用作输出迭代器吗?

seh*_*ehe 8

我建议使用提升范围(算法和适配器)以方便使用,你写道:

boost::copy(
    data | transformed(makeT) | filtered(validate) /* | indirected */, 
    std::back_inserter(queue));
Run Code Online (Sandbox Code Playgroud)

这是一个完整的工作示例:

#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;
}
Run Code Online (Sandbox Code Playgroud)

更新

在这个答案的帮助下:使用boost :: optional和boost :: adapters :: indirected

我现在包括一个优雅的演示,使用indirected范围适配器以及队列的立即输出(取消引用选项):

请注意,对于(智能)指针类型,显然不需要提供pointee<>专业化.我认为这是设计的: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, ", "));
}
Run Code Online (Sandbox Code Playgroud)