简体   繁体   English

如何为模板类重载<< cout?

[英]How to overload << cout for a template class?

We were taught how to overload cout the other day for our program to cout but I don't know how to make it output everything. 前几天我们被教过如何重载cout,以使我们的程序可以cout,但是我不知道如何使它输出所有内容。

 template <NODETYPE>
 friend ostream &operator <<(ostream &, List<NODETYPE>& );


template<typename NODETYPE>
ostream &operator <<(ostream& output, List<NODETYPE>& value)
{ 
    output << value;
    return output;
}

However, my program has at least 5 objects to output and two of them are doubles. 但是,我的程序至少要输出5个对象,其中两个是double。 I get an error for that that says 'double is not a valid type for a template constant parameter' 我收到一个错误消息,说“ double不是模板常量参数的有效类型”

My two problems are: How do I output all my objects and not just the first object; 我的两个问题是:如何输出所有对象,而不仅仅是第一个对象; and how do I get the double to output. 以及如何获得双倍输出。 Please and thanks! 请和谢谢!

EDIT: HUGE EDIT::: 编辑:巨大的编辑:::

Okay, I realized I was doing something wrong, rearranged my header, and source files. 好的,我意识到自己做错了事,重新排列了标题和源文件。

And then I also realized that missing my lecturer's class was one of the biggest mistakes I've ever made. 然后我也意识到,错过讲师的课是我犯过的最大的错误之一。 My next error, was giving you all my assumptions, and not the information that I assumed from. 我的下一个错误是给您我所有的假设,而不是我所假设的信息。

In my assignment, it says: • Write an assignment operator and a friend function to output the linked list. 在我的作业中,它说:•编写一个作业运算符和一个朋友函数来输出链接列表。

in almost every other line of my main function(a function that I'm not allowed to alter), there is a cout: 在我的主要功能的几乎所有其他行中(不允许更改的功能),都有一个提示:

List<int> Li, Li2, Li3;
List<double> Ld, Ld2;

These are my objects. 这些是我的对象。 And all my couts look something like this: 我所有的提示看起来都是这样的:

  cout << "Ld is: " << Ld << endl;

After rearranging my header and source files, I got this error: "no match for 'operator<<' in 'std::operator<<[with_Traits = std::char_traits] (((std::basic_ostream>&)(& std::cout)), ((const char*) 'Ld is"))< 重新排列头文件和源文件后,出现以下错误:“在'std :: operator << [with_Traits = std :: char_traits](((std :: basic_ostream>&)(& std :: cout)),(((const char *)'Ld is“))<

I get that for every single cout statement I have. 我得到的每条关于cout的陈述都可以理解。 It's more information than Ld exit status is 1 or whatever, so I'm going from this. 它的信息比Ld退出状态为1或其他任何信息都多,所以我从这里开始。

I'm still not fully keen on using this ostream overload function, so any help appreciated and thank you so much for your time! 我仍然不太热衷于使用此ostream重载功能,因此感谢您的帮助,并非常感谢您的宝贵时间!

EDIT::-- 编辑:: -

I've put almost all my code in this post: collect2: Ld returned 1 exit status build make error 我已经将几乎所有代码都写在了这篇文章中: collect2:Ld返回了1退出状态构建make错误

If someone could help me with the overload that'd be great, because I think it's the only problem I've got left so I can figure out everything else. 如果有人可以帮助我解决超载问题,那是很棒的,因为我认为这是我唯一剩下的问题,因此我可以找出其他所有问题。

Thanks!! 谢谢!!

You need to perform some kind of iteration over the List<NODETYPE> , printing out each node. 您需要对List<NODETYPE>执行某种迭代,以打印出每个节点。 Otherwise you have an infinite recursion, with the operator calling itself. 否则,您将具有无限递归,操作员会自行调用。

This example prints out the elements separated by a single space, in a single line. 本示例在一行中打印出用单个空格分隔的元素。 I have omitted the details of the iteration mechanism because I don't know your List interface. 由于我不了解您的List接口,因此省略了迭代机制的详细信息。

template<typename NODETYPE>
ostream &operator <<(ostream& output, const List<NODETYPE>& value)
{ 
   for ( node in value) // pseudocode iteration
   {
     output << node << " ";
   }
   return output;
}

This assumes there is an ostream& operator<< for the node types, if not you have to provide that too. 假定节点类型有一个ostream& operator<< ,否则就不必提供该值。 Also, note I pass the list by const reference . 另外,请注意我通过const reference传递列表。 This has many advantages, one of them being you can pass temporary objects. 这有很多优点,其中之一就是您可以传递临时对象。

Concerning the friend declaration, you also need template<typename T> there, but it isn't clear you need the operator to be friend in the first place. 关于friend声明,那里也需要template<typename T> ,但尚不清楚您首先需要运算符成为friend Lists typically provide access to their elements in their public interface. 列表通常在其公共界面中提供对其元素的访问。

List<T> 's operator<< should iterate through each element of type T in the list and call output << element; List<T>operator<<应该遍历列表中每个T类型的元素,并调用output << element; on each. 在每一个上。

Then, make sure each type T that you create a List<T> object with also implements an operator<< which outputs each of its variables you would like it to, in the format you would like it to, such as output << "(" << x << "," << y << ")" . 然后,确保您创建List<T>对象所使用的每个类型T还实现了一个operator<< ,它以您希望的格式输出您想要的每个变量,例如output << "(" << x << "," << y << ")" Built-in types already do this, so for example List<int> will not require this step. 内置类型已经可以执行此操作,因此例如List<int>将不需要此步骤。

1) The friend declaration is unnecessary, unless the NODETYPE you want to use as template argument is a class you defined yourself, and the operator<< you are defining wants to access any private members of NODETYPE . 1)不需要friend声明,除非要用作模板参数的NODETYPE是您自己定义的类, 并且要定义的operator<<想要访问NODETYPE任何私有成员。 It seems that right now, NODETYPE is double , so there is no need for a friend declaration. 现在看来, NODETYPEdouble ,因此不需要friend声明。

If you have other data types you'd like to use as template arguments, and those other data types are your own classes, put a friend declaration inside those classes. 如果您要使用其他数据类型作为模板参数,而这些其他数据类型是您自己的类,则这些类中放置一个friend声明。 (This may be true of the List type, as described below). (这对于List类型可能是正确的,如下所述)。

2) Right now, your operator<< is recursive. 2)现在,您的operator<<是递归的。 You must (as suggested by the other answers) somehow iterate through the list of NODETYPE objects you get: 您必须(按照其他答案的建议)以某种方式遍历所获得的NODETYPE对象的列表:

for(List::const_iterator it = value.begin() ; it != value.end() ; ++it)
  output << *it;

(The above assumes, your List datatype implements begin() , end() and iterators. You may want to use a different way of iterating through the elements of the List . For that, you may actually have to access private members of the List data type, in which case you must declare the operator<< as a friend template (including typename !) inside the List class definition.) (以上假设,您的List数据类型实现了begin()end()和iterators。您可能希望使用另一种方式遍历List的元素。为此,您实际上可能必须访问List私有成员。数据类型,在这种情况下,您必须在List类定义中声明operator<<作为朋友模板(包括typename !)。)

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

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