[BGL] [PropertyMap] Key param is passed by value in put function

Hi to all, I've noticed that the put function that takes a generic put_get_helper map, takes a key param. The question is: why the key param is passed by value? Is any reason for this? The key value is not modified setting the property map. I've noticed it because in my graph type the descriptors are variant, and so every time I've to set a property map, a new copy of the variant is created. I've reported the function below, for sake of comfort. It is in boost/property_map.hpp template <class PropertyMap, class Reference, class K, class V> inline void put(const put_get_helper<Reference, PropertyMap>& pa, K k, const V& v) { static_cast<const PropertyMap&>(pa)[k] = v; } Best regards, Cosimo Calabrese

Cosimo Calabrese wrote:
Hi to all,
I've noticed that the put function that takes a generic put_get_helper map, takes a key param. The question is: why the key param is passed by value? Is any reason for this? The key value is not modified setting the property map.
I've noticed it because in my graph type the descriptors are variant, and so every time I've to set a property map, a new copy of the variant is created.
I've reported the function below, for sake of comfort. It is in boost/property_map.hpp
template <class PropertyMap, class Reference, class K, class V> inline void put(const put_get_helper<Reference, PropertyMap>& pa, K k, const V& v) { static_cast<const PropertyMap&>(pa)[k] = v; }
The same thing is in class iterator_property_map, in operator[] the key value is passed by value: inline R operator[](key_type v) const { return *(iter + get(index, v));} Best regards, Cosimo Calabrese.

I've noticed that the put function that takes a generic put_get_helper map,
takes a key param. The question is: why the key param is passed by value? Is any reason for this? The key value is not modified setting the property map.
The original application of keys for property maps only covered some fairly trivial data types (ints, pointers, and pairs thereof). Passing by value is perfectly acceptable in these cases.
It's likely that the compiler won't actually generate a copy anyways. The compiler is allowed to "elide" or omit a copy construction if it feels that one isn't necessary. There's a good possibility that your key isn't being copied anyways. Dave Abrahams gives a good account of copy elision here: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/. Andrew Sutton andrew.n.sutton@gmail.com

Andrew Sutton wrote:
I've noticed that the put function that takes a generic put_get_helper map,
takes a key param. The question is: why the key param is passed by value? Is any reason for this? The key value is not modified setting the property map.
The original application of keys for property maps only covered some fairly trivial data types (ints, pointers, and pairs thereof). Passing by value is perfectly acceptable in these cases.
It's likely that the compiler won't actually generate a copy anyways. The compiler is allowed to "elide" or omit a copy construction if it feels that one isn't necessary. There's a good possibility that your key isn't being copied anyways. Dave Abrahams gives a good account of copy elision here: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/.
[MSVS 2005, WinXP] Well, debugging in depth my code, every time I pass a variant key by value, the following copy-constructor is called: variant(const variant& operand) { // Copy the value of operand into *this... detail::variant::copy_into visitor( storage_.address() ); operand.internal_apply_visitor(visitor); // ...and activate the *this's primary storage on success: indicate_which(operand.which()); } When the function terminates, the automatic local variable is destroyed by ~variant() { destroy_content(); } Yes, the original project of BGL uses simply integer types as vertex_descriptor, but BGL is similar at STL, and so it is extensible. Someone can creates new containers (graph implementations or graph adaptors) that can use the existing generic algorithms (like Dijkstra), that use the PropertyMap concept; but the code of the PropertyMap implementation requires that the key type is simple. So the algorithm requires it too, similar to a concept. So, it can be said that the new containers that extends BGL must have "simple" descriptors? I think it's an important limitation (perhaps useless) to the extension of BGL. What to you think about? Unfortunately, now I've no time to read the Dave's article, but I'll read it tonight. Thank you, Cosimo Calabrese.

Andrew Sutton wrote:
I've noticed that the put function that takes a generic put_get_helper map,
takes a key param. The question is: why the key param is passed by value? Is any reason for this? The key value is not modified setting the property map.
The original application of keys for property maps only covered some fairly trivial data types (ints, pointers, and pairs thereof). Passing by value is perfectly acceptable in these cases.
Leaving aside whether copy elision is performed or not, isn't this what call_traits<T>::param_type is for, passing built-in types and pointers as T and user-defined types as const T&? (On the other hand, std::pair<int, int> is probably best passed by value, but param_type would be a const reference.) --Jeffrey Bosboom
participants (3)
-
Andrew Sutton
-
Cosimo Calabrese
-
Jeffrey Bosboom