Andrzej, Thank you for your input. It's appreciated. Please find my replies below. On 2016-06-06 18:45, Andrzej Krzemienski wrote:
Hi Vladimir, I am following the discussion about Pimpl here, and it seems to me I understand the idea less and less.
In my view the idea has not changed at all. Not even a little. As I see it the pimpl idea is still 1) to separate interface from the implementation and 2) to hide the implementation. And I personally did not see this thread diverging from these two principal pimpl properties. IMO the discussion revolved around the implementation. Say, Emil (as I understand) was advocating taking the interface separation part to the "extreme" -- eliminating the interface/proxy object altogether and providing the interface via public functions. Domagoj suggested his own alternative implementation also.
My impression is (but I might be wrong here) that people use Pimp for slightly different things and that one solution might not suit all the needs.
Well, I feel that people use pimpl to do #1 (separate) and #2 (hide). If they use pimpl to do something else, then they might be trying the wrong tool. Still, people requirements and priorities are different so, indeed, "one solution might not suit all the needs". That's why the proposal has, in fact, two solutions -- with pointer and value-semantics. More so, this time the proposal is policy-based and extendible. I do not claim to cover every-man requirements and needs. I feel, the design is extendible and sufficiently flexible to accommodate new requirements and needs. That is why I am trying to encourage Domagoj to incorporate his stack-based policy/manager. That way we'd cover all pimpl requirements/expectations that I am aware of so far.
Let me list two use cases that I consider significantly different:
1a. I am selling my own complicated library, and I want to make sure users will never see the source code. I can afford to add some run-time penalty because this is a high-level library and the cost of additional indirection is negligible compared to what the library is doing.
1b. I am a programmer and I use a third party library called LIB1 but I wrap it into a class C because I do not want the users of class C to have any knowledge of LIB1, because next month I want to replace library LIB1 with another library LIB2, and I want to do it seamlessly, without forcing the users of C to recompile anything. Again, the cost of additional indirection is negligible, because what LIB1 and LIB2 do is orders of magnitude more expensive.
2. I want to apply Pimpl to every second class in my program because my code is not performance-critical and I would rather have fast compile-times than fast run-times. A valid trade-off for non-critical parts of the program.
The question is, which of the two (or any other) use cases does your library address?
All three cases seem to be the standard cases for pimpl idiom application as in every case you want separate+hide. I believe the proposed pimpl handles all three. You can deploy pimpl<Foo>::shared or pimpl<Foo>>::unique depending on your circumstances. Better still, if, say, Domagoj decides to contribute his stack-based policy implementation, then, say, pimpl<Foo>::stack might be deployed in applications with stricter efficiency/memory requirements.
Also, I remember that last time the library promoted the use of shared ownership (altering the state of one object immediately alters the states of other objects). The examples from the new dos still seem to imply that. Is it necessary? If for some reason I need the shared ownership I could implement it atop of Pimpl classes using a shared_ptr.
Yes, indeed, I think it is probably a valid point. The thing is I initially wrote it for myself. Probably due to my application-domain specifics I still use pimpl::shared exclusively. So, for me value-pimpl wrapped in shared_ptr seemed like unnecessary inconvenient complexity. If someone else with different priorities decides to submit his value-semantics pimpl and it gets accepted, I'll use it happily as you describe.
But I might be wrong about my understanding of the library. I am really missing the introduction, that would outline the scope of the problems you are addressing, some high level design decisions, and the intended usage.
I tend to agree with you and "some high level design decisions, and the intended usage" would be beneficial as I feel pimpl can be easily mis-used. I would most likely go down that road if pimpl gets into Boost. As it is now I am far from certain if I can justify any additional effort documentation-wise.
For now, the initial example encourages me to use shared semantics, and I feel it is encouraging me to do the wrong thing.
I am not sure I can agree with that. The proposal has two behavioral facets -- pointer-semantics and value-semantics. I had to start the description with one or the other. I happened to choose the pointer-semantics as it's easier to describe as it is shared_ptr-based. After that, again, value-semantics implementation is easier to describe as its underlying implementation mimics shared_ptr's incomplete-type-management functionality. Still, I think you are right sensing that I feel more for pointer-semantics :-) but I would not interpret it as an encouragement to do the wrong thing. :-) Again, I do agree that the documentation needs more "do it", "don't do it", "best practices", etc. I just do not feel like investing more of my time due to high probability of it all wasted.