Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带有迭代器的自定义列表,尝试使指针指向嵌套节点类时出错_C++_Oop_Stl - Fatal编程技术网

C++ 带有迭代器的自定义列表,尝试使指针指向嵌套节点类时出错

C++ 带有迭代器的自定义列表,尝试使指针指向嵌套节点类时出错,c++,oop,stl,C++,Oop,Stl,我正在尝试使用迭代器实现一个简单的列表以供实践,但是我遇到了一个编译错误,我不完全理解,因为我无法修复它。当我试图将迭代器类中的指针指向某个节点时,会出现如下编译错误: 使用类模板需要模板参数列表 以下是产生编译错误的头文件: #ifndef _MY_LIST_H #define _MY_LIST_H #include <memory> template<class T> class MyListItr; template<typename T> c

我正在尝试使用迭代器实现一个简单的列表以供实践,但是我遇到了一个编译错误,我不完全理解,因为我无法修复它。当我试图将迭代器类中的指针指向某个节点时,会出现如下编译错误:

使用类模板需要模板参数列表

以下是产生编译错误的头文件:

#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 
\ifndef\u我的列表\u H
#定义我的列表
#包括
模板
MyListR类;
模板
类MyList{
私人:
内部尺寸;
朋友班;
公众:
类节点{
私人:
T值;
公众:
std::unique_ptr next{nullptr};
Node()=删除;
Node(T&value,MyList::Node*next):value(value),next(next){};
T getVal()常量{返回值;};
void setVal(T值){this->value=value;};
~Node(){};
};
std::唯一的ptr头;
MyList(const MyList&)=删除;
MyList&运算符=(const MyList)=删除;
MyList():_size(0),head(nullptr){};
int size()常量{return_size;};
前空腔推力(T);
T pop_front();
T前()常数;
脱空(T);
myListTR begin(){return myListTR(this->head);};
MyListR端();
typedef mylist迭代器;
typedef MyList::节点值_type;
typedef MyList::Node*指针;
typedef MyList::节点差异类型;
typedef MyList::节点和引用;
};
模板
MyListR类{
MyList::Node*数据;
公众:
MyListTR(MyList::Node*数据):数据(数据){}
布尔运算符!=(myListRconst&)const;
myListTR运算符++();
T算子*();
};
#恩迪夫

我将非常感谢任何关于在哪里寻找线索的帮助或指导。

您的班级
MyListTR
需要

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

public:
    MyListItr(typename MyList<T>::Node*data):data(data) {}
    // ...
};
模板
MyListR类{
typename MyList::Node*数据;
公众:
MyListTR(类型名MyList::节点*数据):数据(数据){}
// ...
};

请注意,您需要使用
typename
关键字来告诉编译器您使用的数据是类型,而不是变量。

您必须指定一个模板参数,以防无法自动推断(在C++17中引入了类模板中的自动模板参数推断)

您有几行,其中不指定模板参数:

myListTR begin(){返回myListTR(this->head);/*这里您忘记了分号*/};
MyList::Node*数据;
MyListTR(MyList::Node*数据):数据(数据){}
您可以按如下方式重写它们:

myListTR begin(){return myListTR(this->head);};
typename MyList::Node*数据;
MyListTR(类型名MyList::节点*数据):数据(数据){}
在第一行中,编译器无法通过返回类型推断
MyListTR
的模板参数(我认为,您认为,如果您在返回类型中指定了模板参数,编译器可以“记住”它),因为,例如,具有不同模板参数的
MyListTR
s可以相互转换

在其他行中,编译器对
MyList
一无所知,因为要实现列表及其迭代器应该具有相同的模板参数并不是很聪明。它更多的是关于用户定义的语义

您必须在第二行和第三行中写入
typename
,因为此类型取决于模板参数。以下是一些解释:

此外,最好重命名以下行中的参数,因为它可能与模板参数名称冲突:

bool操作符=(mylisttr const&T_)const;

此外,您可以尝试在列表的类中声明迭代器,它将自动绑定其中的类型。在这种情况下,您还可以对用户代码隐藏
节点
,并在私有部分声明它。

谢谢,它可以工作。我试图使用
MyList::Node*
,但没有意识到还需要
typename
关键字。是的,编译器需要帮助消除歧义。请参阅以获得一个很好的解释。