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.
From a `unique_ptr` implementation:

```
template<class _ElementT, class _DeleterT = std::default_delete<_ElementT>>
class unique_ptr
{
public:
   // public interface...

private:

  // using empty base class optimization to save space
  // making unique_ptr with default_delete the same size as pointer

  class _UniquePtrImpl : private deleter_type
  {
  public:
     constexpr _UniquePtrImpl() noexcept = default;

     // some other constructors...

     deleter_type& _Deleter() noexcept
     { return *this; }

     const deleter_type& _Deleter() const noexcept
     { return *this; }

     pointer& _Ptr() noexcept
     { return _MyPtr; }

     const pointer _Ptr() const noexcept
     { return _MyPtr; }

  private:
     pointer   _MyPtr;

  };

  _UniquePtrImpl   _MyImpl;

};

```

The `_UniquePtrImpl` class contains the pointer and derives from the `deleter_type`. 

If the deleter happens to be stateless, the base class can be optimized so that it takes no bytes for itself. Then the whole `unique_ptr` can be the same size as the contained pointer - that is: the same size as an ordinary pointer.