Boost logo

Boost :

Subject: Re: [boost] pimpl library proposal
From: Krzysztof Czainski (1czajnik_at_[hidden])
Date: 2010-12-14 11:09:56


2010/12/14 Vladimir Batov <vbatov_at_[hidden]>

> I see. But if I understand correctly, for each smart pointer type, there
>> needs to be a specialization of pimpl_base written from scratch.
>>
>
> I am not sure where you've got that impression from. There is one
> pimpl_base implementation. Pointer- or value-semantics behavior are defined
> by the provided policy class. Pls see the declaration above.

You are right, I misunderstood the definition of pimpl_base. I thought it
was being specialized outside of pimpl, but it is not the case.

template<class T>
struct pimpl /// Generalization of the Pimpl idiom
{
    struct implementation;
    template<class> class impl_ptr;
    template<template<class> class> class pimpl_base;
    /// Convenience typedef to deploy pimpl with value semantics.
    typedef pimpl_base<impl_ptr> value_semantics;
    /// Convenience typedef to deploy pimpl with pointer semantics.
    typedef pimpl_base<boost::shared_ptr> pointer_semantics;
};

So pimpl_base can accept as its template parameter only a template that
takes one argument, like shared_ptr. But it cannot take a template with two
or more parameters, correct?

Why not just do the following?
template < class SmartPtr > class pimpl_base;

Another question: what is the purpose of Your pimpl struct? In other words,
assuming pimpl_base takes a regular template parameter, what is the
advantage of

class MyClass : pimpl<MyClass>::pointer_semantics;

over

class MyClass : pimpl_base< shared_ptr<MyClassImpl> >;

 Now suppose pimpl_base<SmartPtr> does accept any smart pointer: scoped_ptr,
> shared_ptr, clone_ptr, cow_ptr, etc... This is where the creation policy is
> needed. See below...
>

I do not immediately see value in Pimpl accepting "any smart pointer" which
> are policy classes for Pimpl. In fact, I do not know of any policy-based
> class which would accept *any* other class as its policy. I am convinced a
> class to be used as a policy by another class must conform to a certain
> interface.

I admit "any" is not the right word for what I had in mind. I ment some
smart pointer, that the author of the pimpl<> template does not know of;
that smart pointer may not yet exist. Since You place typedefs inside pimpl
(value_semantics, pointer_semantics), I presume You intend to predict all
possible used spart pointers. Otherwise usage would be something like:
class MyClass : pimpl<MyClass>::pimpl_base<MySmartPtr>;
whereas MySmartPtr would have to be a template with one template argument.

 ...
>
>> I am under impression that I do not quite understand what you mean by
>> "customization of the creating policy" either. Isn't that quality achieved
>> by overloaded constructors? If it is so, then the developer provides the
>> set
>> of overloaded constructors for his/her class. Regardsless of those
>> constructors Pimpl does not need to be modified.
>>
>
> The default creation policy would be to create impl on the heap using
> operator new, and passing the resulting pointer to SmartPtr. But for
> example, when using shared_ptr, it might be a good idea to use a)
> make_shared instead of operator new, b) a custom allocator/deleter.
>

I am under impression that the functionality you are suggesting is already
> available.

I can't find it

> Namely, (unless I am still missing your point) "make_shared" quality is
> provided by boost::shared_ptr itself and nothing more needs to be done.

I disagree. Make_shared is provided separatly from shared_ptr, and must be
used instead of operator new, when creating an object.

> As for "custom allocator/deleter" or any other creation policy, then that
> functionality belongs in the "implementation" class and deployed via Pimpl
> interface. So, it seems nothing more needs to be done in Pimpl either.

A constructor from pimpl_base:
pimpl_base() : impl_(new implementation()) {}
It creates implementation using operator new. I was suggesting adding a
factory parameter to pimpl, and delegating creating to the factory, instead
of explicitly calling new implementation()

>
> 3. The user should have no way of telling if MyClass uses pimpl or not. It
>> should be totally transparent.
>>
>
> I happen to disagree. Pimpl implements a certain pattern/idiom which has
> certain qualities. The user deploying that pattern/idiom expects those
> qualities. After all, that's why he/she is deploying that pattern/idiom in
> the first place. I do not immediately see benefits of hiding those
> qualities.

I think we don't understand each other on the definigion of "user". Earlier
I proposed to call a user someone who uses MyClass, and to call an
implementer someone, who implements MyClass and optionally uses pimpl. When
You say "user deploying [pimpl] pattern/idiom", You must mean the
implementer.

However, if You don't think hiding the use of pimpl from the user is a good
thing, then I guess we just have different oppinions about it.

 Well, I understand You expose the operator bool_type for example.
>

> Again, I believe it is part of the idiom. For example, boost::shared_ptr is
> similar in that regard.
>

I see, so we disagree on this. I don't think exposing operator bool_type is
part of the idiom. I think we did not agree on the definition of pimpl, and
I think this leads to all the other things we disagree upon ;-)

[...]

I am sure your Pimpl implementation does everything just the way you want
> it. :-) And if that works better for you than an already available
> component, then I do not see anything wrong with deploying it. I do the same
> all the time. ;-) Still, I suspect if you try deploying your no-frills
> version of a larger scale, it'll start looking more and more as the proposed
> Pimpl. There are countless examples of that behavioral pattern (Java comes
> to mind). As for the proposed Pimpl, let me assure you that the
> functionality provided and described there is there for a reason. May I
> suggest you have another look at the documentation for the proposed Pimpl?
> You might come to appreciate its versatility... or might not. :-)
>
> Good luck and all the best in your endeavors,

Good luck and all the best to You too,

Kris


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk