修改filter_iterator谓词以接受BOOST中的两个参数(二进制fn)

时间:2014-01-19 20:09:48

标签: c++ boost iterator bind boost-graph

参考我之前的问题here,我如何将另一个参数传递给谓词。例如,这里是代码片段。

    // 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, "  " ) );

在上面的代码中,它只需要一个参数(作为edge_descriptor)。我想传递一个逻辑变量,例如对谓词使用int,并将边缘的edge属性与int进行比较,并相应地返回true或false。我知道如何访问edge属性,但我无法将第二个参数传递给谓词。我知道它是一个一元谓词,但无法通过ptr_fun或bind2nd将第二个参数绑定到它。有人可以建议吗?

我可以打印所有边缘,但没有在上面的谓词中插入实际逻辑,正如上面可以注意到的那样。


这是我的仿函数:

    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, " " ) );

创建ffirst时,仿函数正常工作并且输出符合预期。 当创建 llast 时,仿函数会尝试获取图中不存在的任何随机边的信息(boost :: get(NodeInfoPropertyTag()),因为发生了seg故障。

任何建议如何在没有这种情况下创建llast?

1 个答案:

答案 0 :(得分:0)

转换你的仿函数接受两个参数,然后使用std::bind或boost绑定返回一个仿函数,其中一个参数绑定到你想要的值。将此传递给您迭代。

例如,如果您将仿函数签名更改为

Operator()(int v, edge& e)

然后你的绑定变成

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

_1是要传递的参数的占位符。

注意,如果您没有c ++ 11,可以在上面的代码段中用boost替换所有std内容。