On 4/20/07, Dima F.
Aaron Windsor wrote:
The predicates used in a filtered_graph can have non-static members. In particular, I don't see anything wrong with the example you included in your previous email. The predicate needs to be default constructable because in the implementation of filtered_graph, it's stored by value in an iterator and the iterator must be default constructable. But you can still create a non-default instance of your predicate and pass it in to filtered_graph and you should get the results you expect - just make sure it has the correct semantics when default constructed.
Here is an example which (it seems to me) shows that non-static members in predicate can cause a problem (see code below). The program causes segmentation fault, and it happens when pointer to one of non-static members is dereferenced. When I tried to find the reason, it seems that a pointer, when used in operator() during an execution of BFS, contains garbage, that is - it doesn't point to an object it was pointing to after a predicate object was constructed.
When you run the program, it is possible to see according to a log messages that sometimes predicate is constructed using a default constructor, which means that it's members are not copied to a new object.
P.S.: Also, I see that copy-constructor is used, which is somewhat strange - it is written (http://www.sgi.com/tech/stl/DefaultConstructible.html):
"[1] The form X x = X() is not guaranteed to be a valid expression, because it uses a copy constructor. A type that is DefaultConstructible is not necessarily Assignable"
<snip>
cout << "\nAnd in filtered graph:\n\n";
typedef induced_graph_filter
filter_t; filter_t filter(&g, &cont); filtered_graph
g2(g, filter);
Hi Dima,
Well, you do need a copy constructor - look a the line above, where
you pass filter by value in the filtered_graph constructor. The copy
constructor is called there (and anywhere else filter is passed by value).
But even though your filtered graph is declared as a
filtered_graph