I am using a boost::filter_iterator
to filter over of a pair of boost graph vertices as follows:
I have a range of graph vertices using a vertex_iterator
pair <vbegin, vend>.
I want to filter the range using a predicate and the range needs to be grouped
into say 4 sub-ranges
<begin1, end1> ... <begin4, end4>
So I filter over the vertex iterator using boost::filter_iterator
and create 4 subranges.
Such subrange iterator pairs need to be inserted into a container (vector)
std::vector< pair<filter_iterator, filter_iterator> > my_vector
size of vector = 4 (because 4 pairs are inserted)
A filter predicate with a given desired parameter helps define the filter iterator range
<fbegin, fend>
The code is as below :
template<typename Graph>
struct my_filter_pred {
public:
my_filter_pred() { }
my_filter_pred(Graph& _G, int _value) : G(_G), value(_value) { }
template<typename vertex_t>
bool operator() (vertex_t vertex) {
//get property "p" of vertex in graph G
auto p = get (mypropertytype, vertex, G);
return (p.val == value);
}
private:
Graph& G;
}
//get all vertices using vertex iterator
vertex_iterator vbegin, vend;
boost::tie(vbegin, vend) = boost::vertices(G);
The for - loop is as below"
//for each i = 0,1,2,3 -> create a predicate with i as parameter.
//apply the filter predicate over the vertex_iterator range
//insert in the begin, end pair into vector
for (int i=0; i<4; ++i)
{
//for each i, create a filter_pred
my_filter_pred <Graph> filter_pred(G, i)
//now create begin and end filter iterators as follows
auto fbegin = boost::make_filter_iterator< my_filter_pred<Graph>,
vertex_iterator> (filter_pred, vbegin, vend)
auto fend = boost::make_filter_iterator< my_filter_pred<Graph>,
vertex_iterator> (filter_pred, vend, vend)
//fbegin, fend are of type filter iterator
//insert the iterator pair into vector
my_vector.push_back( std::make_pair (fbegin, fend) );
}
Now: the problem testing part:
I am using 2 compilers gcc4.9 and Inter 13.0.1 for testing this code.
Results :
gcc 4.9 --> works correctly, compiles fine and works fine as well.
icpc gives me the following error:
error: implicitly generated assignment operator cannot copy:
reference member "my_filter_pred <Graph>::G [with ... ]"
struct my_filter_pred { ^ detected during:
I googled the error and I found this link on intel's website here which describes about the same error but no information is provided for such error.
How do I solve this ? I tried adding the following into my predicate (function object)
my_filter_pred& operator=(const my_filter_pred&);
my_filter_pred(const my_filter_pred&);
but after that I get "undefined reference to .... " error. How do I explicitly define the copy assignment operator and copy constructor
Since you use a reference Graph& G
in your predicate my_filter_pred
the latter is copy-constructable but cannot be assigned by operator=. But you need operator = in many places of your code.gnable.
I would recommend to change the code as follows
template
struct my_filter_pred {
public:
my_filter_pred() { }
my_filter_pred(Graph& _G, int _value) : G(&_G), value(_value) { }
template<typename vertex_t>
bool operator() (vertex_t vertex) {
//get property "p" of vertex in graph G
auto p = get (mypropertytype, vertex, *G);
return (p.val == value);
}
private:
Graph* G;
}
Now filter predicate is copy-assignable.