I have two questions regarding the design of the BGL. I'm interested in this to get a better understanding of the design choices, which influences how I use the BGL and how I'm building on it. 1) Why is a lot of the function arguments made by value rather than reference? As an example, consider the BFS algorithm, where the documentation states that "[1] Since the visitor parameter is passed by value, if your visitor contains state then any changes to the state during the algorithm will be made to a copy of the visitor object, not the visitor object passed in. Therefore you may want the visitor to hold this state by pointer or reference." It would be much easier to use the visitor objects for keeping state throughout the algorithm if it was passed by reference instead. 2) Non-constness. It seems impossible to use BGL together with code that is "const-correct". If, for instance, I have a function implementing some kind of examining algorithm on a graph (so the graph is passed to it as const), and this algorithm uses breadth_first_search with a visitor that doesn't modify the graph, it still can't be const when passed to breadth_first_search. This only leaves the options of either (i) casting away constness in the call, which is bad because it could introduce bugs later on, or (ii) leaving out const altogether which is not good either. Maybe I've just misunderstood something and this is possible, or perhaps it is impossible to implement BGL in this way? Björn
Hi Bjorn, On Wed, 2 Oct 2002, [iso-8859-1] Bj�rn Lindberg wrote: [snip] yg-boo> 1) Why is a lot of the function arguments made by value rather than yg-boo> reference? As an example, consider the BFS algorithm, where the yg-boo> documentation states that [snip] One of the usage scenarios that we wanted to support with the algorithms was creating visitor objects on the fly, within the argument list of the call to the graph algorithm. In this situation, the visitor object is a temporary object. Now there is a truly unfortunate rule in the C++ std that says a temporary cannot be bound to a non-const reference parameter. So we had to decide whether we wanted to support this kind of usage and go with call-by-value, or not and go with call-by-reference. We chose call-by-value, following in the footsteps of the STL (which passes functors by value). yg-boo> It would be much easier to use the visitor objects for keeping state yg-boo> throughout the algorithm if it was passed by reference instead. yg-boo> yg-boo> 2) Non-constness. It seems impossible to use BGL together with yg-boo> code that is "const-correct". If, for instance, I have a function yg-boo> implementing some kind of examining algorithm on a graph (so the yg-boo> graph is passed to it as const), and this algorithm uses yg-boo> breadth_first_search with a visitor that doesn't modify the graph, yg-boo> it still can't be const when passed to breadth_first_search. This yg-boo> only leaves the options of either (i) casting away constness in yg-boo> the call, which is bad because it could introduce bugs later on, yg-boo> or (ii) leaving out const altogether which is not good either. yg-boo> yg-boo> Maybe I've just misunderstood something and this is possible, or yg-boo> perhaps it is impossible to implement BGL in this way? If you look at the docs for BFS, you'll see that one version takes the graph non-const, and the other takes the graph as a const reference. The reason is that BFS modifies the color map during the search. The version of the algorithm that takes the graph non-const may be getting the color map from the graph, as an internal property map, so in this case BFS is modifying the graph in some sense. The version of BFS that takes the graph as a const reference has a separate parameter for the color map. I suggest that you use the non-named template parameter version that takes the graph by const reference. Regards, Jeremy ---------------------------------------------------------------------- Jeremy Siek http://php.indiana.edu/~jsiek/ Ph.D. Student, Indiana Univ. B'ton email: jsiek@osl.iu.edu C++ Booster (http://www.boost.org) office phone: (812) 855-3608 ----------------------------------------------------------------------
Jeremy Siek wrote:
Hi Bjorn,
On Wed, 2 Oct 2002, [iso-8859-1] Björn Lindberg wrote: [snip] yg-boo> 1) Why is a lot of the function arguments made by value rather than yg-boo> reference? As an example, consider the BFS algorithm, where the yg-boo> documentation states that [snip]
One of the usage scenarios that we wanted to support with the algorithms was creating visitor objects on the fly, within the argument list of the call to the graph algorithm. In this situation, the visitor object is a temporary object. Now there is a truly unfortunate rule in the C++ std that says a temporary cannot be bound to a non-const reference parameter. So we had to decide whether we wanted to support this kind of usage and go with call-by-value, or not and go with call-by-reference. We chose call-by-value, following in the footsteps of the STL (which passes functors by value).
Ah yes, I forgot about that rule. I was thinking that since the temporary is in scope for the whole expression, this would still work. I forgot that it won't for non-const references.
yg-boo> 2) Non-constness. It seems impossible to use BGL together with yg-boo> code that is "const-correct". If, for instance, I have a function yg-boo> implementing some kind of examining algorithm on a graph (so the yg-boo> graph is passed to it as const), and this algorithm uses yg-boo> breadth_first_search with a visitor that doesn't modify the graph, yg-boo> it still can't be const when passed to breadth_first_search. This yg-boo> only leaves the options of either (i) casting away constness in yg-boo> the call, which is bad because it could introduce bugs later on, yg-boo> or (ii) leaving out const altogether which is not good either. yg-boo> yg-boo> Maybe I've just misunderstood something and this is possible, or yg-boo> perhaps it is impossible to implement BGL in this way?
If you look at the docs for BFS, you'll see that one version takes the graph non-const, and the other takes the graph as a const reference. The reason is that BFS modifies the color map during the search. The version of the algorithm that takes the graph non-const may be getting the color map from the graph, as an internal property map, so in this case BFS is modifying the graph in some sense. The version of BFS that takes the graph as a const reference has a separate parameter for the color map.
I suggest that you use the non-named template parameter version that takes the graph by const reference.
I see. To be honest, I find the BFS docs to be somewhat confusing. For instance I haven't been able to find what bgl_named_params is. So I've looked at examples, and my BFS invocations typically look something like this boost::breadth_first_search(tree, root(tree), boost::visitor(visitor)); I've been looking at bgl_named_params just now, but I can't really figure out how to use it. I guess I'm already using it with the line above, but I just copied the use of visitor(...) from an example, I can't say that I know what it does. Speaking of visitors, I find that I often want my visitors to store or access data for every vertex in the graph. This leads me to use property maps (or just plain old std::vectors) a lot. Is creating a property map an expensive operation? How about access, is it done in O(1) time? It seems the best idiom here is to pass a property map to the visitor's constructor, letting the visitor keep a reference to it, so that it is available for the visitor methods, eg discover_vertex(...). It would be more elegant to hide the visitor's functionality a bit more, but the only way I can see to do that is by letting discover_vertex(...) create the property map on every call, which is possible since it is passed the graph as an argument. This seems far too expensive though. Björn
participants (2)
-
Björn Lindberg
-
Jeremy Siek