Subject: Re: [boost] [paired ptr] Proposing a new smart pointer object for managing bidirectional relationships between objects
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2010-05-03 11:14:00
Dan Walters wrote:
> > Your "Usage" section should use initialization rather than
> > assignment for paired_cat and paired_dog. Indeed, from the
> > surrounding text, it would seem that calling set_owner() is
> > the only way to indicate the owner and that means it is
> > possible to not specify an owner. It would be better if the
> > constructor required an owner so the user is forced to
> > initialize the instance with one. Doing so will eliminate
> > the "unfortunate" sentence.
> I was using initialization however this does cause a warning c4355
> inside the user defined class constructor. warning C4355: 'this' :
> used in base member initializer list
> I could disable the warning in the paired_ptr header as the usage is
> safe however this is fairly bad practice as it would result in the
> users project having the warning disabled, and probably against boost
> guidelines. Thus I opted for an initialization function.
That's an MSVC-specific warning. Use pragmas push, disable, and pop, conditionally compiled for MSVC, to manage that warning.
> > The type is named "paired_ptr" so why does "pair" appear in
> > member functions like "connect_pair" and "disconnect_pair?"
> I take it that you are suggesting a more suitable name would be
> "connect_to_paired_ptr"? That would be more descriptive.
No. I was implying "connect" and "disconnect" for those two. There are other possibilities to explore, too. You could use assignment in lieu of "connect," but then it would be difficult to distinguish between connecting and copy assignment. (The "disconnect" complement would be "release.") You could use operator +=() for "connect" and operator -=() for "disconnect," but I think those will raise more eyebrows than their worth. Anyway, I wanted less repetitive not more verbose.
> > The callbacks should be boost::functions for maximum flexibility.
> The problem here comes where I am specifying member functions to be
> called back. boost::function does not support member functions and
> recommends std::bind1st functionality. This results in three options:
Yes, that's an unfortunate side effect.
> 1. use member functions in the current manner.
> 2. use function objects using boost::function
> 3. use bind1st and support both at the cost of less tidy code.
> There is a clear advantage in specifying member functions rather than
> say, void callback_connect(owner_type* p_owner,
> paired_ptr<owner_type,other_type>* p_paired_ptr) as it is much tidier
Don't assume that the object type for the callback member function pointer is the owner type.
> to program and removes the need of global functions or function
> objects. On the other hand, Your point of using boost::function is
> persuasive as function objects are not a bad alternative and will
> extend the ability of callback to allow other functions rather than
> just member functions. I have a feeling that implementing this will
> mean the user implementation will be difficult. I will take a second
Using Boost.Function makes your callback support more flexible, which makes it more useful to users. However, supporting member functions is less clean as you mention. How about the following:
- Support boost::function for maximum flexibility
- Provide a member function template that takes a T * and a T member function pointer
That makes the calling syntax as simple as possible while maximizing flexibility.
> > The callbacks should know the paired_ptr invoking them,
> > because a legitimate reaction might be to modify the
> > paired_ptr's state and using boost::function, the callback
> > may not be a member function or there may be more than one in
> > a UDT and the callback would need to disambiguate.
> I have already added this functionality since posting here :) But
> again, the callbacks cannot have the option of being either a normal
> function or member function as the parameter lists are different.
> Perhaps the correct decision is for callback functions to be static
> member functions or regular functions via boost::function.
I fail to understand the problem. In each case you are invoking a functor with a reference to a paired_ptr. (You could even support overloading for const and non-const access.) What you need is type erasure to make the callback invocation ignorant of how the underlying function is invoked. IOW, you want a member function pointer invocation, via Boost.Function, say, to look just like calling a non-member function pointer or function object.
Rob Stewart robert.stewart_at_[hidden]
Software Engineer, Core Software using std::disclaimer;
Susquehanna International Group, LLP http://www.sig.com
IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk