
Hi, With current implementation of ptr_map::insert(), if an exception is thrown, the objected pointed by the passed pointer is deleted. Is this really providing strong guarantee as documented? I understand strong guarantee as described here. http://www.boost.org/community/exception_safety.html
The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started. I think ptr_map::insert() doesn't provide this guarantee because deleting the object is a change of the program state.
As more concrete problem, see the attached code. I couldn't find any way to provide strong guarantee for delayed_inserter::insert_ready() using ptr_map. I want ready_value unchanged if an exception is thrown during the insertion. Looking for a solution on a similar situation, I found constructors of shared_ptr. Its documentation clearly says that "If an exception is thrown, delete p is called". And for auto_ptr version, it provides strong guarantee by taking the auto_ptr as non-const reference. I think ptr_map::insert() should follow this manner; document the deletion on exception for raw pointer version, and provide strong guarantee with insert(const key_type& key, std::auto_ptr<U>& x) . The the auto_ptr& version can be a better replacement of the raw pointer version. The required temporary of auto_ptr, instead of key_type, is more expressive (about the purpose of the temporary), and matches the Best Practices shown in the documentation of shared_ptr. http://www.boost.org/libs/smart_ptr/shared_ptr.htm#BestPractices But, introducing the auto_ptr& version seems to cause some change of behavior in client codes using the current pass-by-value version. Is it valid to request (create a ticket) for strong guaranteed (taking auto_ptr&) version while having this compatibility concern? Regards. -- k_satoda #include <memory> #include "boost/ptr_container/ptr_map.hpp" namespace ptr_map_insert_strong_guarantee_demo { class value { public: explicit value(int source); // ... }; class delayed_inserter { public: // ... // This is called from context that knows key and source of value, // but doesn't know the time of insertion. void ready_new(int key, int source) { // OK. // This implementation offers strong guarantee for this call. std::auto_ptr<value> new_value(new value(source)); ready_key = key; ready_value = new_value; } // This is called from context which doesn't know key and value, // but knows the time of insertion. void insert_ready() { if (ready_value.get() != 0) { // I want to offer strong guarantee for this call, // but boost::ptr_map deosn't provide the way to do that; // *** ready_value is deleted when an exception is thrown. *** map.insert(ready_key, ready_value); } } // ... private: int ready_key; std::auto_ptr<value> ready_value; boost::ptr_map<int, value> map; // ... }; }