简体   繁体   English

使用模板实现好友重载<<运算符

[英]Implementation of friend overload << operator with templates

I can't figure out the correct syntax for templated friend overloaded operators. 我无法找出模板化的朋友重载运算符的正确语法。 Using the code (I'm only showing the relevant stuff) from the class header (please don't tell me to change anything from this section): 使用类标题中的代码(我仅显示相关内容)(请不要告诉我从此部分进行任何更改):

#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>&);
};

This is where the implementation comes into play, and I can't figure out the syntax. 这是实现起作用的地方,我无法弄清楚语法。

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
   }

What do I need to change in each of those three lines to make this work? 为了使这项工作有效,我需要对这三行进行什么更改?

I keep getting compiler errors: 我不断收到编译器错误:

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

I guess it might be those: 我想可能是那些:

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

lines. 线。 You didn't specify the type of a template: 您未指定模板的类型:

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

so compiler couldn't match declarations with definitions. 因此编译器无法将声明与定义匹配。

So declarations: 所以声明:

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

and definitions: 和定义:

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

Also to prevent compiler from complaining about not declared templates add declarations before class definition. 另外,为防止编译器抱怨未声明的模板,请在类定义之前添加声明。

Final results: 最终结果:

#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 it printed: 对我来说,它打印:

List
Stack
Queue

Here and here you have some nice examples. 您在这里这里都有一些不错的示例。

EDIT: You were right, I made some mistakes. 编辑:你是对的,我犯了一些错误。 Corrected the answer to the working one. 更正了工作中的答案。

there are some weird things here. 这里有些奇怪的事情。

firstly the error message renders ostream differently, the fact that it qualifies the return value as std::ostream& and not the parameter parsed in seems a bit fishy - but it could be a red herring. 首先,错误消息呈现的ostream有所不同,它将返回值限定为std :: ostream&而不是解析的参数的事实似乎有点可疑-但这可能是一个红色鲱鱼。

it is always a shame to see "using namespace std;". 看到“使用命名空间标准”总是很可惜的。 i consider the using keyword to be absolutely forbidden - so i have no idea what problems or changes this might cause. 我认为绝对禁止使用using关键字-因此我不知道这可能导致什么问题或更改。 i simply suspect it is related. 我只是怀疑这是相关的。

now - to debug this properly i'd suggest replacing the operator and friend with regular function templates and breaking the access levels to allow that test (ie remove private etc.), then introduce each element one at a time until you find which part is actually causing the problem. 现在-要正确调试,我建议用常规功能模板替换操作员和朋友,并破坏访问级别以进行该测试(即删除私有等),然后一次介绍每个元素,直到找到哪个部分是真正引起问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM