0

So I have this templated class called list

//List.h
#ifndef LIST_H
#define LIST_H
#include<fstream>

template <class T>
class List
{
    private:
        struct ListNode
        {
           T value;
           ListNode* next;
           ListNode* prev;

           ListNode(T value1, ListNode* next1 = NULL, ListNode* prev1 = NULL)
           {
            value = value1;
            next = next1;
            prev = prev1;
           }
        };
        ListNode* head;
        ListNode* tail;

   public:
       List() {head = NULL; tail = NULL;};
       ~List();
       void PrintForward(std::ostream &out);
       void PrintBackward(std::ostream &out);
       void InsertFront(const T &item);
       void InsertRear(const T &item);
       bool InsertAsNth(int N, const T &item);
       bool DeleteFront(T &val);
       bool DeleteRear(T &val);
       bool DeleteNth(int N, T &val);
       int DeleteAllOccur(const T &item);

       std::ostream& operator<< (std::ostream &out, List::ListNode const* p);

};
#endif

Now I have been trying to get this to compile but with no success. I know it has to do with the way I have the ostream operator overloaded but unfortunately I really do not know/could not find a better way.

also this is my compiler error

 warning C4346: 'List<T>::ListNode' : dependent name is not a type prefix with 'typename' to indicate a type
4

3 回答 3

3
std::ostream& operator<< (std::ostream &out, List::ListNode const* p);

必须成为

std::ostream& operator<< (std::ostream &out, typename List::ListNode const* p);

甚至可能

std::ostream& operator<< (std::ostream &out, typename List<T>::ListNode const* p);

更明确。

因为::ListNode是模板类的依赖类型,ListC++ 编译器需要一点提示。在这种情况下,警告实际上非常有用,对于许多与模板相关的警告来说,这不能说:)

于 2013-09-06T13:59:52.010 回答
1

编译器错误准确地说明了问题所在以及您必须做什么:List<T>::Node是依赖于模板参数的限定 ID,因此编译器无法确定Node是类型还是值。所以你必须typename在它之前写,告诉编译器这Node是一个类型。

我建议您查看这个问题:我必须在哪里以及为什么要放置“模板”和“类型名称”关键字?

于 2013-09-06T14:03:02.523 回答
0

您的代码至少存在两个主要问题。最关键的是,你正在创建operator<<一个成员,并试图给它三个参数,这是完全非法的。如果第一个参数是std::ostream&,则无法将其定义为成员;它必须是免费功能。如果它还需要访问私人数据,那么您必须将其设为朋友。但请注意:

friend std::ostream& operator<<( std::ostream&, typename List::ListNode const* );

结交非模板函数的朋友。模板的每个实例化都有一个不同的非模板函数。这很少是想要的。您可以使特定的模板实例化成为朋友,但前提是事先声明了模板函数。在这种情况下这是不可能的,因为函数的参数之一具有嵌套类型。解决这个问题的更惯用的方法(无论如何,根据我的经验)是定义朋友内联:

friend std::ostream& operator<<( std::ostream& dest, typename List::ListNode const& p )
{
    //  ...
}

在这种情况下,operator<<也是一个非模板函数,但定义嵌套在类模板中,因此您将自动获得该函数的新实例。

于 2013-09-06T15:07:57.620 回答