Nikki Locke <nikki@trumphurst.com>: Oct 14 10:23PM Available C++ Libraries FAQ URL: http://www.trumphurst.com/cpplibs/ This is a searchable list of libraries and utilities (both free and commercial) available to C++ programmers. If you know of a library which is not in the list, why not fill in the form at http://www.trumphurst.com/cpplibs/cppsub.php Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website. |
Paavo Helde <myfirstname@osa.pri.ee>: Oct 14 10:23AM +0300 On 14.10.2017 1:40, Alf P. Steinbach wrote: >> used otherwise in the codebase). > I think maybe better to provide a constructor that forwards arguments to > make_shared. You mean a static factory function? Yes I do that as well. But this does not solve the issue that a new std::shared_ptr can be constructed accidentally from 'this' or from a C++ reference to the object. Such a construction would actually work for some kind of smartpointers, but not for std::shared_ptr, and may create a lot of hidden bugs in the codebase when replacing the old smartpointer by the standard std::shared_ptr. Been there, done that... Cheers Paavo |
"Öö Tiib" <ootiib@hot.ee>: Oct 14 06:27AM -0700 On Friday, 13 October 2017 23:37:40 UTC+3, Vir Campestris wrote: > class "shared_from_this" that allows you to hand out shared pointers safely. > The first time you assign a pointer from your object it sets up the > shared_ptr, links the internal weak_ptr, and all is fine. Yes you are correct. Note that it is unusual case since the programmers usually create new shared_ptr with make_shared or allocate_shared or provide also deleter as well. When someone constructs shared_ptr from raw pointer (without also providing deleter) then I feel that it strongly smells like newbie and is potentially copy-paste from stackoverflow or other newbie site. Can anyone bring sane counter-example? > If some **** later calls std::shared_ptr(this) you get an entirely new > shared pointer, with a different ref count. Yes, when constructing a std::shared_ptr for an object that is already managed by another std::shared_ptr then constructor is not required to check for that (despite it is required to store weak reference to enable_shared_from_this subobject) and so it will always lead to undefined behavior. > If the STL is smart enough to detect the first case why doesn't it give > an error in the second? > I know a codebase where it would have saved lots of problems :( Because it is not required. The 'enable_shared_from_this' was limited feature up to C++17 since there was even no way to check if the object was managed by 'shared_ptr' at all or wasn't. Therefore usage of 'enable_shared_from_this' involved ensuring that *every* object of that type was *always* already managed by 'shared_ptr'. From C++17 we can finally make a check that (note how confusing interface) when 'pT->weak_from_this().expired()' then the object pointed at is not managed by 'shared_ptr<T>'. That still does not make constructing shared_ptr from pT non-smelly or non-dangerous. However it at least removes the curse that something derived from 'enable_shared_from_this' was not passable by value, usable as automatic object, usable as element of container or usable as member of class without rendering the whole 'enable_shared_from_this' useless. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 14 08:44PM +0200 On 10/14/2017 3:27 PM, Öö Tiib wrote: > From C++17 we can finally make a check that (note how confusing > interface) when 'pT->weak_from_this().expired()' then the object > pointed at is not managed by 'shared_ptr<T>'. I don't get what you mean here. I'm not familiar with the `expired` function but one could always check a weak pointer by trying to convert it to `shared_ptr`, and, checking in cppreference, I see that `expired` was introduced in C++11 (maybe it was there always in Boost, I don't know, but since the function is is irrelevant its date of introduction doesn't matter). As far as I know C++17 still lacks a way to check if a type T is derived from some accessible and unique base class `enabled_shared_from_this<U>`, doesn't it? > automatic object, usable as element of container or usable as > member of class without rendering the whole 'enable_shared_from_this' > useless. I don't get this either. I think there is an issue with /moving/ an object of a type derived from `enable_shared_from_this`. But a weak pointer can be copied just fine, can't it? Cheers!, - Alf |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 14 08:47PM +0200 On 10/14/2017 9:23 AM, Paavo Helde wrote: > You mean a static factory function? Yes I do that as well. But this does > not solve the issue that a new std::shared_ptr can be constructed > accidentally from 'this' or from a C++ reference to the object. Not entirely sure what you mean, but I didn't mean in-addition-to, I meant instead-of. Sort of like this: namespace cppx { using std::enable_if_t; using std::enable_shared_from_this; using std::forward; using std::make_shared; using std::shared_ptr; template< class D, class B > using Is_derived_and_base = std::is_base_of<B, D>; template< class Referent > class Shared_ptr : public shared_ptr<Referent> { public: template< class... Args > Shared_ptr( Args&&... args ) : shared_ptr<Referent>( make_shared<Referent>( forward<Args>( args )... ) ) {} }; } // namespace cppx Possibly also allow construction from a raw pointer to type derived from `enable_shared_from_this`, and possibly also support construction from raw pointer + deleter, but not just from any raw pointer. > but not for std::shared_ptr, and may create a lot of hidden bugs in the > codebase when replacing the old smartpointer by the standard > std::shared_ptr. Uhm? Cheers!, - Alf |
"Öö Tiib" <ootiib@hot.ee>: Oct 14 12:35PM -0700 On Saturday, 14 October 2017 21:44:25 UTC+3, Alf P. Steinbach wrote: > > interface) when 'pT->weak_from_this().expired()' then the object > > pointed at is not managed by 'shared_ptr<T>'. > I don't get what you mean here. I will gladly try to explain then. > cppreference, I see that `expired` was introduced in C++11 (maybe it was > there always in Boost, I don't know, but since the function is is > irrelevant its date of introduction doesn't matter). The issue was not checking if 'weak_ptr' is pointing at valid object. The issue was that 'enable_shared_from_this::weak_from_this()' was not yet present in C++14 and so calling pT->weak_from_this() did not compile. Calling pT->shared_from_this() however was undefined behavior on case the object pointed at by pT was not managed by shared_ptr in C++14 (it throws bad_weak_ptr in C++17). > As far as I know C++17 still lacks a way to check if a type T is derived > from some accessible and unique base class > `enabled_shared_from_this<U>`, doesn't it? May be that is not needed. On general case 'std::is_base_of' is plenty. To avoid edge cases it is required from programmer that the 'enable_shared_from_this' base should be unique and accessible. > > member of class without rendering the whole 'enable_shared_from_this' > > useless. > I don't get this either. Here I am in dim what you don't get. I meant that now we can check if object (derived publicly and uniquely from 'enable_shared_from_this') is actually managed by shared_ptr. That significantly relaxes its usage. > I think there is an issue with /moving/ an object of a type derived from > `enable_shared_from_this`. Copying enable_shared_from_this does not copy the weak reference because it does not make sense if to think about it a bit. > But a weak pointer can be copied just fine, can't it? Yes, copying weak_ptr increases weak count of managed object. With it there are no issues. |
Vir Campestris <vir.campestris@invalid.invalid>: Oct 14 09:24PM +0100 On 14/10/2017 14:27, Öö Tiib wrote: > also providing deleter) then I feel that it strongly smells like > newbie and is potentially copy-paste from stackoverflow or other > newbie site. Can anyone bring sane counter-example? Yes. If the constructor is private to force use of a factory function make_shared won't compile. (I tried and failed to work out the correct friend statement, then gave up) Thanks everyone. Andy |
JiiPee <no@notvalid.com>: Oct 14 02:22PM +0100 vec contains many elements. This is not my real code, I only did it to illustrate the problem. But I know already it was the unsigned issue. thanks On 13/10/2017 18:36, Vlad from Moscow wrote: |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment