Как std:: unique_ptr не имеет накладных расходов на размер?

Если размер пустого класса не может быть 0, то какая магия делает std:: tuple, поэтому sizeof unique_ptr возвращает 8 в 64-битной машине?

В unique_ptr член определяется как:

  typedef std::tuple<typename _Pointer::type, _Dp>  __tuple_type;                 
  __tuple_type  _M_t;

Где _Dp - класс делетера.

Компилятор - версия gcc 4.7.1 (Debian 4.7.1-7)

Ответ 1

Причина в том, что typename _Dp = default_delete<_Tp> - пустой класс, а шаблон tuple использует пустую оптимизацию базового класса.

Если вы создаете экземпляр unique_ptr без удаления по умолчанию, вы должны увидеть увеличение размера.

Ответ 2

unique_ptr, как указано, может иметь нулевые служебные данные, потому что единственное, что необходимо для его реализации, - это изменить процесс копирования/перемещения необработанного указателя; дополнительная информация не требуется. Поэтому unique_ptr не нужно хранить ничего, кроме указателя, и может быть того же размера, что и указатель.

Что касается вашей конкретной реализации, это достигается; Только большинство производных типов должны иметь размер больше нуля. Пустые базовые классы могут принимать нулевые байты. Для стандартных реализаций библиотек довольно часто используется оптимизация так называемого "пустого базового класса" для всех видов вещей, от распределителей без сохранения в контейнерах до кортежей.