Пользовательский список с итератором, ошибка при попытке сделать указатель на класс вложенного узла - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь реализовать простой список с итератором для практики, однако я столкнулся с ошибкой компиляции, которую я не до конца понимаю, я не смог ее исправить. Когда я пытаюсь сделать указатель в своем классе Iterator на узел, я получаю ошибку компиляции следующим образом:

использование шаблона класса требует списка аргументов шаблона

Вот мой заголовок файл, который выдает ошибку компиляции:

#ifndef _MY_LIST_H
#define _MY_LIST_H
#include <memory>



template<class T> 
class MyListItr;

template<typename T>
class MyList {
private:
    int _size;
    friend class MyListItr<T>;
public:
    class Node {
    private:
        T value;
    public:
        std::unique_ptr<MyList::Node> next{ nullptr };

        Node() = delete;
        Node(T& value, MyList::Node* next) :value(value), next(next) {};
        T getVal()const { return value; };
        void setVal(T value) { this->value = value; };
        ~Node() {};
    };

    std::unique_ptr<MyList::Node> head;
    MyList(const MyList<T>&) = delete;
    MyList& operator=(const MyList<T>) = delete;
    MyList() :_size(0), head(nullptr) {};
    int size()const { return _size; };
    void push_front(T);
    T pop_front();
    T front()const;
    void remove(T);
    MyListItr<T> begin() {return MyListItr(this->head); };
    MyListItr<T> end();
    typedef MyListItr<T> iterator;
    typedef MyList<T>::Node value_type;
    typedef MyList<T>::Node* pointer;
    typedef MyList<T>::Node difference_type;
    typedef MyList<T>::Node& reference;

};

template<typename T>
class MyListItr {
    MyList::Node* data;

public:
    MyListItr(MyList::Node*data) : data(data) {}

    bool operator!=(MyListItr<T>const&) const;
    MyListItr<T> operator++();
    T operator*();
};


#endif 

Буду признателен за любую помощь или указание, где искать любые подсказки.

Ответы [ 2 ]

1 голос
/ 06 апреля 2020

Ваш класс MyListItr должен быть

template<typename T>
class MyListItr {
    typename MyList<T>::Node* data;

public:
    MyListItr(typename MyList<T>::Node*data):data(data) {}
    // ...
};

Обратите внимание, что вам нужно использовать ключевое слово typename, чтобы сообщить компилятору, что вы используете тип, а не переменную.

0 голосов
/ 06 апреля 2020

Необходимо указать параметр шаблона в случае, если он не может быть автоматически выведен (автоматическое c Вывод параметра шаблона в шаблонах классов был введен в C ++ 17).

У вас есть несколько строк, где вы не указывайте параметры шаблона:

MyListItr<T> begin() { return MyListItr(this->head); /* Here you forget semicolon */};
MyList::Node* data;
MyListItr(MyList::Node*data):data(data) {}

Вы должны переписать их следующим образом:

MyListItr<T> begin() { return MyListItr<T>(this->head);};
typename MyList<T>::Node* data;
MyListItr(typename MyList<T>::Node*data):data(data) {}

В первой строке компилятор не может вывести параметр шаблона MyListItr по типу возвращаемого значения (Я думаю, вы подумали, что если вы указали параметр шаблона в типе возврата, компилятор может «запомнить» его), потому что, например, MyListItr s с другим параметром шаблона могут быть преобразованы друг в друга ...

В других строках компилятор ничего не знает о MyList, потому что не совсем понятно, что ваш список и его итератор должны иметь одинаковые параметры шаблона. Это больше о пользовательской семантике.

Вы должны написать typename во второй и третьей строках, потому что этот тип зависит от параметра шаблона. Вот некоторые объяснения: https://en.cppreference.com/w/cpp/language/dependent_name

Более того, вам лучше переименовать аргумент в следующей строке, поскольку он может конфликтовать с именем параметра шаблона:

bool operator!=(MyListItr<T> const& T_)const;

Кроме того, вы можете попытаться объявить итератор внутри класса вашего списка, и он будет автоматически связывать типы внутри. В этом случае вы также можете скрыть Node от кода пользователя и объявить его в приватном разделе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...