Question: I am reading "Effective Modern C++". In the item related to `std::unique_ptr` it's stated that if the custom deleter is a stateless object, then no size fees occur, but if it's a function pointer or `std::function` size fee occurs. Could you explain why?

Let's say that we have the following code:

```
auto deleter_ = [](int *p) { doSth(p); delete p; };
std::unique_ptr<int, decltype(deleter_)> up(new int, deleter_);

```

To my understanding, the `unique_ptr` should have an object of type `decltype(deleter_)` and assign `deleter_` to that internal object. But obviously that's not what's happening. Could you explain the mechanism behind this using smallest possible code example?

Answer: 
A `unique_ptr` must always store its deleter. Now, if the deleter is a class type with no state, then the `unique_ptr` can make use of [empty base optimization](http://en.cppreference.com/w/cpp/language/ebo) so that the deleter does not use any additional space.

How exactly this is done differs between implementations. For instance, both [libc++](http://llvm.org/svn/llvm-project/libcxx/trunk/include/memory) and MSVC store the managed pointer and the deleter in a [compressed pair](http://www.boost.org/doc/libs/release/libs/utility/doc/html/compressed_pair.html), which automatically gets you empty base optimization if one of the types involved is an empty class.

From the libc++ link above

```
template <class _Tp, class _Dp = default_delete<_Tp> >
class _LIBCPP_TYPE_VIS_ONLY unique_ptr
{
public:
    typedef _Tp element_type;
    typedef _Dp deleter_type;
    typedef typename __pointer_type<_Tp, deleter_type>::type pointer;
private:
    __compressed_pair<pointer, deleter_type> __ptr_;

```

libstdc++ [stores the two](https://github.com/gcc-mirror/gcc/blob/8ced49657ce78d11e6bb72780939245ee8105ae7/libstdc%2B%2B-v3/include/bits/unique_ptr.h#L155) in an `std::tuple` and some Google searching suggests their `tuple` implementation employs empty base optimization but I can't find any documentation stating so explicitly.

In any case, [this example](http://coliru.stacked-crooked.com/a/e86bdf01d34d12d3) demonstrates that both libc++ and libstdc++ use EBO to reduce the size of a `unique_ptr` with an empty deleter.
If the deleter is stateless there's no space required to store it. If the deleter is not stateless then the state needs to be stored in the `unique_ptr` itself.  

`std::function` and function pointers have information that is only available at runtime and so that must be stored in the object alongside the pointer the object itself. This in turn requires allocating (in the `unique_ptr` itself) space to store that extra state.

Perhaps understanding the [Empty Base Optimization](http://en.cppreference.com/w/cpp/language/ebo) will help you understand how this could be implemented in practice.  

The [`std::is_empty`](http://en.cppreference.com/w/cpp/types/is_empty) type trait is another possibility of how this could be implemented.

How exactly library writers implement this is obviously up to them and what the standard allows.