
Simply small change, curious as to what others think: I'll illustrate with a trivial example: struct foo { virtual ~foo() { } }; struct bar : foo { }; typedef shared_ptr<foo> fooptr; typedef shared_ptr<bar> barptr; void some_func(weak_ptr<foo> wf) { barptr pb = wf.lock<bar>(); } // currently the way to do this is (as I am sure everyone knows) void some_func(weak_ptr<foo> wf) { barptr pb = dynamic_pointer_cast<bar>(wf.lock()); } My suggestion seems easier to read. Would require no additional overhead and would preserve existing behavior. I suppose you could provide a static and dynamic version: lock_static<bar> and lock_dynamic<bar> Any thoughts? Or is the general concensus that ideas like this are something indivudual people should do in their own source? Jeff

Jeff Williams wrote:
Simply small change, curious as to what others think:
I'll illustrate with a trivial example:
struct foo { virtual ~foo() { } }; struct bar : foo { };
typedef shared_ptr<foo> fooptr; typedef shared_ptr<bar> barptr;
void some_func(weak_ptr<foo> wf) { barptr pb = wf.lock<bar>(); }
// currently the way to do this is (as I am sure everyone knows) void some_func(weak_ptr<foo> wf) { barptr pb = dynamic_pointer_cast<bar>(wf.lock()); }
My suggestion seems easier to read. Would require no additional overhead and would preserve existing behavior.
However, there is no indication that wf.lock<bar> does a cast, or which kind of cast is being done.
I suppose you could provide a static and dynamic version:
lock_static<bar> and lock_dynamic<bar>
Any thoughts? Or is the general concensus that ideas like this are something indivudual people should do in their own source?
Something like that. In general, libraries expose a "minimal but complete" interface, and utility functions are left to the users (whose preferences usually differ). "Boilerplate" functions or components (nearly every user needs to have them, and they are a de-facto standard) are an exception, of course.

From: "Peter Dimov" <pdimov@mmltd.net>
Jeff Williams wrote:
struct foo { virtual ~foo() { } }; struct bar : foo { };
typedef shared_ptr<foo> fooptr; typedef shared_ptr<bar> barptr;
void some_func(weak_ptr<foo> wf) { barptr pb = wf.lock<bar>(); }
// currently the way to do this is (as I am sure everyone knows) void some_func(weak_ptr<foo> wf) { barptr pb = dynamic_pointer_cast<bar>(wf.lock()); }
My suggestion seems easier to read. Would require no additional overhead and would preserve existing behavior.
However, there is no indication that wf.lock<bar> does a cast, or which kind of cast is being done.
Typically, hiding needed casts in a function is beneficial, and documentation can take care of explaining what's occuring under the covers.
I suppose you could provide a static and dynamic version:
lock_static<bar> and lock_dynamic<bar>
Any thoughts? Or is the general concensus that ideas like this are something indivudual people should do in their own source?
Something like that. In general, libraries expose a "minimal but complete" interface, and utility functions are left to the users (whose preferences usually differ).
"Boilerplate" functions or components (nearly every user needs to have them, and they are a de-facto standard) are an exception, of course.
The better way to handle such extensions is via non-member function templates: barptr pb = lock<bar>(wf); Such function templates can be put in various places, as appropriate, but they don't have to clutter weak_ptr's header unless they are widely applicable. That syntax has the advantage of being useful with other types, too, if warranted. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (3)
-
Jeff Williams
-
Peter Dimov
-
Rob Stewart