Is it possible to use boost::filter_iterator for output?

后端 未结 1 626
甜味超标
甜味超标 2020-12-09 22:28

I am using std::transform with an std::back_inserter to append elements to an std::deque. Now the transformation may fail and will re

1条回答
  •  北荒
    北荒 (楼主)
    2020-12-09 23:05

    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 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    typedef boost::optional T;
    typedef std::deque 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 
    #include 
    #include 
    
    #include 
    
    namespace boost {
        template struct pointee > {
            typedef typename optional

    ::value_type type; }; } typedef boost::optional 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(std::cout, ", ")); }

    0 讨论(0)
提交回复
热议问题