如何处理模板化类中的ostream运算符重载

时间:2013-09-06 13:57:40

标签: c++ class templates operator-overloading ostream

所以我有这个名为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

现在我一直试图让它编译但没有成功。我知道这与我ostream运算符重载的方式有关,但不幸的是我真的不知道/找不到更好的方法。

这也是我的编译错误

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

3 个答案:

答案 0 :(得分: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是模板化类List的依赖类型,并且C ++编译器需要一些提示。在这种情况下,警告实际上是非常有用的,对于许多与模板相关的问题,这个问题无法说明:)

答案 1 :(得分:1)

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

我建议你查看这个问题:Where and why do I have to put the "template" and "typename" keywords?

答案 2 :(得分: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<<也是非模板化函数,但是 该定义嵌套在类模板中,因此您将获得 一个新的函数实例。