unique_ptr and the pointer to implementation idiom
Last time, I wrote about unique_ptr
and PImpl, demonstrating why you can't use a unique_ptr
for PImpl. This time, I'd like to show you how you can make unique_ptr
work with PImpl.
Remember, this is the code I initially presented back in When an empty destructor is required.
1 2 3 4 5 6 7 |
|
You saw in my last post Smart pointers and the pointer to implementation idiom that in contrast to the shared_ptr
a unique_ptr
doesn't do type erasure and hence eagerly tries to find the definition of the data pointer.
Providing a custom deleter function that you forward declare is one trick to how you can use a unqiue_ptr
with PImpl. The following code illustrates this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
I'm using C++20 for the solution because, that way, my code is shorter. InA, I provide a custom deleter. Thanks to C++20, I can use a capture-less lambda inside a decltype
expression. The lambda takes an Orange
pointer as a parameter. In the lambda's body, I forward declare the real deleter function B OrangeDeleter
and call the function in the new line. All I have to do is provide OrangeDeleter
in the implementation file of Apple
, and I can completely hide Orange
.
If you wonder about the lambda I'm using, please refer to this post for more context: Understanding the inner workings of C++ smart pointers - The unique_ptr with custom deleter or the YouTube episode C++ Insights - Episode 34: C++20: Captureless lambdas in unevaluated contexts. You can also find more about C++20s enhancements to lambda in my book Programming with C++20 - Concepts, Coroutines, Ranges, and more.
Andreas