std::shared_ptr<T> operator->() {
auto shared = lock();
if(shared == nullptr) {
throw std::bad_weak_ptr(); // or some other exception
}
return shared;
}
This would be implemented as follows:std::shared_ptr<T> operator->() { auto shared = lock(); if(shared == nullptr) { throw std::bad_weak_ptr(); // or some other exception } return shared; }
The lifetime of the returned shared_ptr nicely scopes a member function call.Thoughts?
So you can write:
ptr->foo();
instead of
ptr.lock()->foo();
On 15 January 2015 at 15:51, Taylor Holliday <wthol...@gmail.com> wrote:This would be implemented as follows:std::shared_ptr<T> operator->() { auto shared = lock(); if(shared == nullptr) { throw std::bad_weak_ptr(); // or some other exception } return shared; }
The lifetime of the returned shared_ptr nicely scopes a member function call.Thoughts?What is the use case (other than "we can")? It means that the caller isn't participating in ownership yet still expects someone else to be keeping the object alive. Why wouldn't I just pass a shared_ptr instead?
Note: if the answer is "to detect programming bugs", such as how some people abuse things like vector::at(), I am firmly against that, as that use case is far better served by asserts rather than pretending it is a recoverable error.
On 2015–01–16, at 9:16 AM, Taylor Holliday <wthol...@gmail.com> wrote:I was using weak_ptr in a template that expects something to behave like a pointer. Ended up having to add a generic function overloaded on weak_ptr that would lock (I couldn't simply pass in a shared_ptr). Turned out not to be that bad actually.
On 2015–01–16, at 9:16 AM, Taylor Holliday <wthol...@gmail.com> wrote:I was using weak_ptr in a template that expects something to behave like a pointer. Ended up having to add a generic function overloaded on weak_ptr that would lock (I couldn't simply pass in a shared_ptr). Turned out not to be that bad actually.weak_ptr isn’t a pointer, it’s a contract for getting a pointer.
Hmm. It seems pretty easy to shoot yourself in the foot that way anyway if you don't know what you're doing:weak_ptr<Thing> ptr = get_thing();auto& foo = ptr.lock()->some_member;use(foo); // foo might be long gone by this point
This paper by Stroustrup would seem to endorse my suggestion, no?
On Saturday, January 17, 2015 at 2:10:10 PM UTC-8, Tony V E wrote:On Thu, Jan 15, 2015 at 7:54 PM, Taylor Holliday <wthol...@gmail.com> wrote:Hmm. It seems pretty easy to shoot yourself in the foot that way anyway if you don't know what you're doing:weak_ptr<Thing> ptr = get_thing();auto& foo = ptr.lock()->some_member;use(foo); // foo might be long gone by this pointYep, so let's not make it worse.
And note an important difference in form: x-> vs x()->Any time you see function()-> you should question the lifetime of the return.Without the () it is easy to forget that x-> might be a function call, and thus something to question.Also I'd prefer not to end up with code like:x = ptr->x;y = ptr->y;
...where each -> is a separate call to lock().Tony
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
On Sat, Jan 17, 2015 at 6:08 PM, Taylor Holliday <wthol...@gmail.com> wrote:This paper by Stroustrup would seem to endorse my suggestion, no?No.- if A then B doesn't mean if B then A.
Stroustrup is saying *some* wrapping makes sense (or is common, whether it makes sense or not), not that your wrapping makes sense - ie he doesn't mention weak pointers- that paper is 15 years old, I'm not sure even Stroustrup agrees with it
grab-lock do-something release-lock
IMO, his wrapper might make sense for trace-logging, but I still wouldn't recommend it for mutex locking (even if he mentions that as an example), and I suspect he wouldn't really recommend it for locking either - locking on each access is too inefficient, and you don't get a consistent snap-shot of the object you are accessing (ie between ptr->x and ptr->y accesses, the object could change - is that expected?). I think the locking example falls into the "common" or "possible" category, not the "recommended" category.
But it does highlight that weak_ptr is somewhat poorly named. Thanks. I think naming is important; unfortunately too late for this one :-(Tony