shared_ptr and container iterators

Hi all, just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators. struct MyItem { int value; }; struct MyContainer { typedef std::set<boost::shared_ptr<MyItem> > MySet; MySet set; }; int main(int argc, char* argv[]) { MyContainer mc; boost::shared_ptr<MyItem> p(new MyItem); p->value = 5; mc.set.insert(p); MyContainer::MySet::const_iterator i = mc.set.begin(); // cannot mutate shared_ptr pointed to by iterator: ok //(*i).reset(new MyItem); // cannot change ptr but can change value: ok (*i)->value = 6; MyContainer::MySet::iterator j = mc.set.begin(); (*j).reset(new MyItem); // how to do this? // should not change ptr nor MyItem std::set<boost::shared_ptr<const MyItem> >::const_iterator k = mc.set.begin(); return 0; }

just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators.
IIUC, the following answers your question: http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#FAQ <<Q. Why is operator->() const, but its return value is a non-const pointer to the element type? A. Shallow copy pointers, including raw pointers, typically don't propagate constness. It makes little sense for them to do so, as you can always obtain a non-const pointer from a const one and then proceed to modify the object through it.shared_ptr is "as close to raw pointers as possible but no closer".>>

On 16/04/2012 20:06, Igor R wrote:
just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators.
IIUC, the following answers your question: http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#FAQ <<Q. Why is operator->() const, but its return value is a non-const pointer to the element type? A. Shallow copy pointers, including raw pointers, typically don't propagate constness. It makes little sense for them to do so, as you can always obtain a non-const pointer from a const one and then proceed to modify the object through it.shared_ptr is "as close to raw pointers as possible but no closer".>>
Got a recommendation as to how to get this const-correct? I'm kinda clueless right now... Or does the above faq mean it just cant be done? struct MyItem { int value; }; struct MyContainer { protected: typedef std::set<boost::shared_ptr<MyItem> > MySet; MySet set; public: MySet::iterator stuff_begin(); // should not change ptr nor MyItem nor set XXX::const_iterator stuff_begin() const; };

On Tue, Apr 17, 2012 at 8:56 AM, Johannes Totz <johannes@jo-t.de> wrote:
On 16/04/2012 20:06, Igor R wrote:
just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators.
IIUC, the following answers your question: http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#FAQ <<Q. Why is operator->() const, but its return value is a non-const pointer to the element type? A. Shallow copy pointers, including raw pointers, typically don't propagate constness. It makes little sense for them to do so, as you can always obtain a non-const pointer from a const one and then proceed to modify the object through it.shared_ptr is "as close to raw pointers as possible but no closer".>>
Got a recommendation as to how to get this const-correct? I'm kinda clueless right now... Or does the above faq mean it just cant be done?
struct MyItem { int value; };
struct MyContainer { protected: typedef std::set<boost::shared_ptr<MyItem> > MySet; MySet set;
public: MySet::iterator stuff_begin();
// should not change ptr nor MyItem nor set XXX::const_iterator stuff_begin() const; };
Maybe you can use a transform_iterator to map the shared_ptr<MyItem> to a shared_ptr<MyItem const> (if such a conversion exists, I'm not sure)? - Jeff

IIUC, the following answers your question: http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#FAQ <<Q. Why is operator->() const, but its return value is a non-const pointer to the element type? A. Shallow copy pointers, including raw pointers, typically don't propagate constness. It makes little sense for them to do so, as you can always obtain a non-const pointer from a const one and then proceed to modify the object through it.shared_ptr is "as close to raw pointers as possible but no closer".>>
Got a recommendation as to how to get this const-correct? I'm kinda clueless right now... Or does the above faq mean it just cant be done?
I'm afraid it can't be done with shared ptr.

On 16-04-2012 16:19, Johannes Totz wrote:
Hi all,
just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators.
Maybe Boost.PtrContainer can be used. It doesn't allow shared ownership though. -Thorsten

On 17/04/2012 08:48, Thorsten Ottosen wrote:
On 16-04-2012 16:19, Johannes Totz wrote:
Hi all,
just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators.
Maybe Boost.PtrContainer can be used. It doesn't allow shared ownership though.
Thanks for suggestion. All pointed-to objects are shared though...

On 17-04-2012 17:42, Johannes Totz wrote:
On 17/04/2012 08:48, Thorsten Ottosen wrote:
On 16-04-2012 16:19, Johannes Totz wrote:
Hi all,
just started playing with boost::shared_ptr. How do I get a const iterator pointing to a shared_ptr pointing to a const object? See code below, I'd like to prevent a MyItem being changed through const iterators.
Maybe Boost.PtrContainer can be used. It doesn't allow shared ownership though.
Thanks for suggestion. All pointed-to objects are shared though...
Ok. Then maybe the best to do is to create a const-propagating shared_ptr. You can do so by A. inhirit privately or embed as member a shared ptr B. Implemenet -> and * in a const propagating manner. C. Implement other functions as needed. -Thorsten
participants (4)
-
Igor R
-
Jeffrey Lee Hellrung, Jr.
-
Johannes Totz
-
Thorsten Ottosen