Boost logo

Boost :

From: Vladimir Batov (batov_at_[hidden])
Date: 2007-10-13 22:27:21

From: "Peter Dimov" <pdimov_at_[hidden]>

>> Anyway, I see you'd been preparing your implementation for Boost but it
>> does
>> not seem to have ever made it. That's unfortunate. How come it was
>> abandoned
>> and sent to the fringes of Yahoo archives?
> I have a "policy" of not proposing libraries that I don't use. impl_ptr
> was
> a nice experiment, but shared_ptr happens to satisfy all my
> implementation-hiding needs. :-)

That's fair enough. I myself certainly always use shared_ptr-based Pimpl.
However, due to specificity of my task I tend to use Pimpls with pointer
semantics only. In this discussion thread as soon as I mentioned Pimpl
people asked for value semantics and I believe that's reasonable. Are you
saying you've been using shared_ptr for Pimpls with value semantics? Then, I
guess, you'd have to explicitly write Pimpl(Pimpl const&), Pimpl::op=(),
Pimpl::op==(). Something straightforward like

template<class T>
class Pimpl

    Pimpl(Pimpl const that) : impl_(new T(*that.impl_)) {}
    Pimpl& operator=(Pimpl const& that) const { *impl_ = *that.impl_; return
*this; }
    bool operator==(Pimpl const& that) const { return *impl_ =
*that.impl_; }


    class Implementation;
    boost::shared_ptr<Implementation> impl_;

does not cut it as it does not compile unless Pimpl::Implementation is
visible. So, we have to apply the same incomple-type management technique as
deployed in shared_ptr and your other impl_ptr. Like

template<class T>
class Pimpl

    Pimpl(Pimpl const that) : impl_(trait_->copy(*that.impl_)) {}
    Pimpl& operator=(Pimpl const& that) const { trait_->assign(*impl_,
*that.impl_); return *this; }
    bool operator==(Pimpl const& that) const { return
trait_->compare(*impl_, *that.impl_); }


    class Implementation;
    boost::shared_ptr<Implementation> impl_;
    trait* trait_;

and that seems like a serious hassle unless generalized. So, it feels the
Pimpl situation is begging for your impl_ptr. Don't you agree?

Unfortunately, neither your impl_ptr nor Alan Griffith grin_ptr seem to be
complete. Alan's implementation is very basic and does not seem to handle
run-time polymorphic classes. Your impl_ptr is better in that regard and
closer to shared_ptr (for obvious reasons :-)). However, dynamic_traits
extends incomplete-type management only onto copy when I feel it needs to do
the same for assignment and comparison. I do not feel impl_ptr's approach to
assignment via deletion and copy construction is 100% kosher.

Ideally, impl_ptr and shared_ptr ought to share the same scaffolding with
different deep/shallow-copy policies. It's sad, it has not worked out that

Getting back to Pimpl, I feel that a thin interface layer on top of
shared_ptr or impl_ptr would alleviate much annoyance while writing Pimpls.
It can be as simlpe as

class Test1 : boost::pimpl<Test1, pointer_semantics>
    only Test interface here

class Test2 : boost::pimpl<Test2, value_semantics>
    only Test interface here

So, I guess, my question is how would you suggest I approach the issue? I'd
really like to hear you view on the subject.


Boost list run by bdawes at, gregod at, cpdaniel at, john at