The std::unique_ptr template has two parameters: the type of the pointee, and the type of the deleter. This second parameter has a default value, so you usually just write something like std::unique_ptr<int>.
The std::shared_ptr template has only one parameter though: the type of the pointee. But you can use a custom deleter with this one too, even though the deleter type is not in the class template. The usual implementation uses type erasure techniques to do this.
Is there a reason the same idea was not used for std::unique_ptr?
Part of the reason is that
shared_ptrneeds an explicit control block anyway for the ref count and sticking a deleter in isn’t that big a deal on top.unique_ptrhowever doesn’t require any additional overhead, and adding it would be unpopular- it’s supposed to be a zero-overhead class.unique_ptris supposed to be static.You can always add your own type erasure on top if you want that behaviour- for example, you can have
unique_ptr<T, std::function<void(T*)>>, something that I have done in the past.