Каков наилучший способ обработки типов шаблонов указателей и не указателей в пользовательском контейнере типа std :: vector? - PullRequest
0 голосов
/ 23 января 2020

Итак, я создаю свой собственный динамический c контейнер массива, похожий на std :: vector, для развлечения / исследования. Урезанный заголовок для моего контейнера выглядит так:

template<class ElementClass> 
class Array
{
public:
    Array(class Allocator* allocator, size_t initialCapacity);
    ~Array();

    ...

private:
    class Allocator* allocator;
    ElementClass* pFirst;
    size_t m_capacity;
    size_t m_size;
};

До сих пор мой класс Array прекрасно работал с любым типом, который я предоставляю шаблону (woohoo!). Тем не менее, моя текущая реализация, кажется, задыхается, когда я пытаюсь использовать указатель вместо типа объекта. Хороший пример этого был бы в деструкторе:

template<class ElementClass>
Array<ElementClass>::~Array()
{
    for (size_t c = 0; c < m_capacity; c++)
    {
        pFirst[c]->~ElementClass();
    }
    allocator->free(pFirst);
}

Это, очевидно, приводит к неприятной ошибке, потому что если бы я, например, сделал Array<int*>, то ElementClass преобразуется в int* , на который компилятор по праву спотыкается и продолжает падать вниз по длинной лестнице. Также есть несколько других мест, где подобные вещи происходят, но я оставил их для краткости.

Итак, мой вопрос: как правильно обрабатывать этот класс шаблонов, чтобы он позволял мне создавать контейнер шаблонов, который может обрабатывать как указатели, так и не указательные типы? Должен ли я использовать какую-то технику специализации шаблонов для функций, где возникает такая проблема? Заранее спасибо. :)

1 Ответ

1 голос
/ 23 января 2020

То, что вы делаете, это вызов dtor для элемента, на который указывает указатель, а не для значений указателя, хранящихся в массиве. Если ваш массив делает что-то кроме этого в dtor, он делает это неправильно ....

template<class ElementClass>
Array<ElementClass>::~Array()
{
    for (size_t c = 0; c < m_size; c++)
    {
        pFirst[c].~ElementClass();
    }
    allocator->free(pFirst);
}

Вызов dtor для объектов, на которые указывают указатели в массиве, кажется мне очень опасным , Кто знает, откуда взялись эти указатели (NULL, переменные, выделенные стеком, и т. Д. c).

Массив "ошибка C2325: 'int *': неожиданный тип справа от '-> ~': ожидаемый 'int'".

Элемент ElementClass имеет значение тип int*. Вы пытаетесь разыменовать этот указатель, поэтому тип теперь int. Затем вы пытаетесь вызвать dtor для типа int* на int.

...