Пример уникального типа хранилища unique_ptr? - PullRequest
2 голосов
/ 07 июня 2011

Говард Хиннант объяснил , что unique_ptr также может использовать пользовательский тип хранения . В качестве примера он упоминает " общая память ".

Он только дает грубую идею (что хорошо для быстрого вступления). Но может ли кто-нибудь завершить свой пример для «пользовательского типа хранилища» (будь то общая память или нет)?

Для поддержки размещения unique_ptr в общей памяти пользовательский удалитель может содержать пользовательский тип указателя (обычно это не настоящий указатель в приложениях с общей памятью). Один просто помещает вложенный тип , называемый pointer , который эмулирует поведение указателя в вашем удалителе, общедоступный:

template <class T>
class MyDeleter
{
public:
    class pointer
    {
     public:
        friend bool operator==(pointer x, pointer y);
        friend bool operator!=(pointer x, pointer y);
        // ...
    };

    void operator()(pointer p);
};

void test()
{
    unique_ptr<int, MyDeleter<int> > p;
    MyDeleter<int>::pointer p2 = p.get();  // A custom pointer type used for storage
}

Я подозреваю, что // ... должно быть расширено, и test(), вероятно, сделает некоторые дополнительные вещи в реальном примере "пользовательского типа хранилища".

Может кто-нибудь сказать мне, где он / она

  • фактически уже использовал эту настройку ,
  • и в этом контексте ,
  • какой какой код настройки , (на //... вероятно)
  • и как код клиента использует его? (на test() вероятно)

Ответы [ 2 ]

2 голосов
/ 08 июня 2011

20.7.1.2 / 3 сообщает нам

Тип unique_ptr:: Указатель должен удовлетворять требованиям NullablePointer (17.6.3.3).

Согласно 17.6.3.3, для типа P эти требования:

  • P is EqualityComparable , DefaultConstructible , CopyConstructible , CopyAssignable и Разрушаемый
  • Lvalue P swappable
  • Инициализация значения объекта типа P дает нулевое значение типа, и нулевое значение должно быть эквивалентно толькосам по себе
  • объект типа P может быть контекстно преобразован в bool
  • объект типа P может быть инициализирован и назначен nullptrи это приводит к нулевому значению
  • Объект типа P может быть равенством по сравнению с nullptr, и сравнение истинно тогда и только тогда, когда объект имеет нулевое значение
  • Ни одна из требуемых операций не может генерироваться (но не требует явного noexcept или throw())

Обратите особое внимание, что operator* и operator-> фактически не требуются.Также обратите внимание, что встроенные числовые типы удовлетворяют всем требованиям, кроме nullptr инициализация / назначение.

Например, следующий тип должен удовлетворять всем требованиям:

class handle {
    int id;
  public:
    // default and nullptr constructors folded together
    handle(std::nullptr_t = nullptr) : id(0) { }

    explicit operator bool() { return l.id != 0; }

    friend bool operator ==(handle l, handle r) { return l.id == r.id; }
    friend bool operator !=(handle l, handle r) { return !(l == r); }

    // default copy ctor and operator= are fine

    // explicit nullptr assignment and comparison unneeded
    // because of implicit nullptr constructor

    // swappable requirement fulfilled by std::swap
}
2 голосов
/ 08 июня 2011

Возможно, вас заинтересует boost :: offset_ptr , который послужил мотивирующим сценарием использования для этой точки настройки в unique_ptr. offset_ptr - это полностью разработанный тип указателя, который можно установить в пользовательский инструмент удаления с помощью простого определения типа. Его вариант использования - поместить unique_ptr в разделяемую память.

...