朋友重载的实现<<运算符与模板

时间:2013-11-27 02:01:04

标签: c++ templates syntax operator-overloading friend

我无法找出模板化朋友重载运算符的正确语法。从类标题中使用代码(我只显示相关内容)(请不要告诉我更改本节中的任何内容):

#include <iostream>
using namespace std;

template <typename T>
class List;
template <typename T>
class Queue;
template <typename T>
class Stack;

template <typename T>
class Node{
   private:
      friend class List<T>;
      friend class Stack<T>;
      friend class Queue<T>;
      friend ostream& operator<< <>(const ostream&, const List<T>&);
      friend ostream& operator<< <>(const ostream&, const Stack<T>&);
      friend ostream& operator<< <>(const ostream&, const Queue<T>&);
};

template <typename T>
class List{
   public:
      friend ostream& operator<< <>(const ostream&, const List<T>&);
};

template <typename T>
class Stack{
   public:
      friend ostream& operator<< <>(const ostream&, const Stack<T>&);
};

template <typename T>
class Queue{
   public:
      friend ostream& operator<< <>(const ostream&, const Queue<T>&);
};

这是实现发挥作用的地方,我无法弄清楚语法。

template <typename T>
ostream& operator<<(const ostream& cout, const List<T>& toPrint){ <-- what do I change here?
   // irrelevant body
   }

template <typename T>
ostream& operator<<(const ostream& cout, const Stack<T>& toPrint){ <-- what do I change here?
   // irrelevant body
   }

template <typename T>
ostream& operator<<(const ostream& cout, const Queue<T>& toPrint){ <-- what do I change here?
   // irrelevant body
   }

我需要更改这三行中的每一行才能使其正常工作?

我不断收到编译错误:

error: template-id ‘operator<< <>’ for ‘std::ostream& operator<<(const ostream&, const Queue<Card>&)’ does not match any template declaration

2 个答案:

答案 0 :(得分:1)

我猜可能是那些:

  friend ostream& operator<< <>(const ostream&, const List<T>&);
  friend ostream& operator<< <>(const ostream&, const Stack<T>&);
  friend ostream& operator<< <>(const ostream&, const Queue<T>&);

行。您没有指定模板的类型:

  friend ostream& operator<< <T>(ostream&, const List<T>&);
  friend ostream& operator<< <T>(ostream&, const Stack<T>&);
  friend ostream& operator<< <T>(ostream&, const Queue<T>&);

因此编译器无法将声明与定义匹配。

声明:

friend ostream& operator<< <T>(const ostream&, const List<T>&);

和定义:

template <typename T>
ostream& operator<<(ostream& cout, const List<T>& toPrint) {
    // irrelevant body
}

还要防止编译器抱怨未声明的模板在类定义之前添加声明。

最终结果:

#include <iostream>
using namespace std;


// Class delcarations - we need them to declare functions

template <typename T>
class List;
template <typename T>
class Stack;
template <typename T>
class Queue;


// operator<< function declaration informs compiler that there is function that can be befriended

template <typename T>
ostream& operator<<(ostream&, const List<T>&);
template <typename T>
ostream& operator<<(ostream&, const Stack<T>&);
template <typename T>
ostream& operator<<(ostream&, const Queue<T>&);


// Class definitions

template <typename T>
class Node{
    private:
        friend class List<T>;
        friend class Stack<T>;
        friend class Queue<T>;
};

template <typename T>
class List{
    public:
        friend ostream& operator<< <T>(ostream&, const List<T>&);
};

template <typename T>
class Stack{
    public:
        friend ostream& operator<< <T>(ostream&, const Stack<T>&);
};

template <typename T>
class Queue{
    public:
        friend ostream& operator<< <T>(ostream&, const Queue<T>&);
};


// Actual implemetations

template <typename T>
ostream& operator<<(ostream& out, const List<T>& toPrint) {
    out << "List";
    return cout;
}

template <typename T>
ostream& operator<<(ostream& out, const Stack<T>& toPrint) {
    out << "Stack";
    return out;
}

template <typename T>
ostream& operator<<(ostream& out, const Queue<T>& toPrint) {
    out << "Queue";
    return out;
}

// Template instantations test

int main() {
    List<int>  list;
    Stack<int> stack;
    Queue<int> queue;

    cout << list  << endl
         << stack << endl
         << queue << endl;

    return 0;
}

for me打印出来:

List
Stack
Queue

Herehere你有一些不错的例子。

编辑:你是对的,我犯了一些错误。纠正了工作的答案。

答案 1 :(得分:0)

这里有一些奇怪的事情。

首先,错误消息以不同的方式呈现ostream,事实上它将返回值限定为std :: ostream&amp;而不是解析的参数看起来有点可疑 - 但它可能是一个红色的鲱鱼。

看到“using namespace std;”总是很遗憾。我认为禁止使用using关键字 - 所以我不知道这可能导致什么问题或变化。我只是怀疑它是相关的。

现在 - 要正确调试这个我建议用常规功能模板替换操作员和朋友并打破访问级别以允许该测试(即删除私有等),然后一次引入一个元素,直到找到哪部分实际上是导致问题。