Question

with reference to my previous question here, how do i pass another argument to the predicate. for example here is the code snippet.

    // want this to take 2 arguments instead of one. (like a binary function)
    template < typename edge >
    struct isRequiredEdge {
    bool operator()( edge& e) {
    return true;
    }
    };

    // out_edge_iterators
    out_edge_it beg, end;
    boost::tie(beg, end) = boost::out_edges( v, G);
    typedef boost::filter_iterator< isRequiredEdge<ed_t>, out_edge_it > FilterIter;


    isRequiredEdge<ed_t> predicate;
    FilterIter ffirst ( predicate, beg, end  );
    FilterIter llast  ( predicate, end  );


    std::copy( ffirst, llast, std::ostream_iterator< ed_t > (std::cout, "  " ) );

In the above code, it takes only one argument ( as edge_descriptor ). I want to pass a logic variable, say for example an int to the predicate, and compare the edge property of the edge with the int and return true or false accordingly. I know how to access edge property, but i am unable to pass the 2nd parameter to the predicate. I am aware it is a unary predicate, but unable to bind the 2nd argument to it through ptr_fun or bind2nd. Could anyone suggest ?

I am able to print all the edges, but without the actual logic inserted in the above predicate, as once can notice above.


here is my functor:

    template < typename edge, typename graph >
    struct isRequiredEdge {
    isRequiredEdge( int t, graph& G ) : m_t(t), m_G(G) { }
    bool operator()( edge e ) {
    cout << " edge " << e << ": t = " << m_t  << endl;
    EdgeInfo* ei = &boost::get(EdgeInfoPropertyTag (), m_G, e ); 
    if(ei->time == m_t)
            return true;
    else 
          return false;
    }
    private:
       int m_t;
       graph m_G;

    };

    // out_edge_iterator
    boost::tie(beg, end) = boost::out_edges(*inf_it, G);

    // typedef filter_iterator for type out_edge_it
    typedef boost::filter_iterator< isRequiredEdge<ed_t, Graph>, out_edge_it > FilterIter;

    // create predicate object passing parameters such as time t and graph G.
    isRequiredEdge<ed_t, Graph> predicate(t, G);

    // define iterators here
    FilterIter ffirst ( predicate, beg, end  );
    FilterIter llast  ( predicate, end  );
    std::copy( ffirst, llast, std::ostream_iterator< ed_t > (std::cout, " " ) );

when ffirst is created, the functor works correctly and output is as expected. when llast is created, the functor tries to get information for any random edge which does not exist in the graph ( boost::get(NodeInfoPropertyTag ( ) ) due to which seg fault happens.

Any suggestions how do i create llast without this happening?

Was it helpful?

Solution

Convert you functor to accept two arguments, then use std::bind, or boost bind to return you a functor where one of the arguments is bound to the value you want. Pass this to you iteration.

For example, if you change your functor signature to,

Operator()(int v, edge& e)

Then your bind becomes

auto f = std::bind(isRequiredEdge<>::operator(), &predicate, 42, _1);

_1 is a placeholder for the argument to be passed in.

Note, you can replace all the std stuff with boost in the above snippet, if you don't have c++11.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top