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
