在 ostream 重载友元函数中使用向量

Posted

技术标签:

【中文标题】在 ostream 重载友元函数中使用向量【英文标题】:using vector in ostream overload friend function 【发布时间】:2014-01-31 03:08:46 【问题描述】:

我有一个名为“KeyedCollection”的模板类,其中包含将数据插入向量以及流出数据的函数。向量是一个私有成员函数。我似乎无法弄清楚如何在我重载的 ostream 朋友函数中使用来自这个向量的信息。注意:我无法更改类的一般结构和函数参数,它们必须保持原样。我列出了所有类以供参考,但有问题的函数是最后一个。

#include "stdafx.h"
#include <iostream>
#include <vector>
#include "Windows.h"
#include <string>

using namespace std;

template <class K, class T> 
class KeyedCollection 
public:
  // Create an empty collection
  KeyedCollection();

  // Return the number of objects in the collection
  int size() const;

  // Insert object of type T with a key of type K into the
  // collection using an “ignore duplicates” policy
  void insert(const K&, const T&);

  // Output data value of objects in the collection,
  // one data value per line
  friend ostream& operator<<(ostream&,
                             const KeyedCollection&);

private:
  // Insert required members here
        int objSize;
vector<T> objects;

;

template<class K, class T>
KeyedCollection<K,T>::KeyedCollection() 

objSize = 0;
vector<T> objects;
   

template<class K, class T>
int KeyedCollection<K,T>::size() const 

    objSize = objects.size();

return objSize;
 

template<class K, class T> 
void KeyedCollection<K,T>::insert(const K&,const T& c) 

objects.push_back(c);


// !!! function i am trying to define !!!
template<class K, class T>
ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst) 

outstream<<inst<<endl;

return outstream;

另外,我收到一条错误提示

“致命错误 LNK1120:1 个未解决的外部问题”

还有一个说

“错误 LNK2019: 无法解析的外部符号”类 std::basic_ostream > & __cdecl 运算符 &,class KeyedCollection const &)" (??6@YAAAV?$basic_ostream@DU?$ char_traits@D@std@@@std@@AAV01@ABV?$KeyedCollection@HVCustomer@@@@@Z) 在函数_main中引用" ...

作为一个附带问题,你知道那些可能是什么吗?

【问题讨论】:

将朋友&lt;&lt; 的实现移动到类的主体中,错误会消失还是替换为其他错误? 好吧,我试过了,但我认为我做的不对...你能把函数定义为 ostream& KeyedCollection::operator& inst) outstream 在类的主体中。而不是 friend 声明末尾的 ; 而是放入 然后写正文然后放入 。换行符可选。 还是不行,只是返回更多错误 不同的错误?顺便说一句,上面的代码在头文件和 cpp 文件之间拆分了吗?我更改后的错误是我更改前的错误的子集吗?我更改后的错误是什么?没有工作是非常无益的。 【参考方案1】:

cppreference 和 Johannes Schaub - litb 都提供了相同的方法来使其工作。

您想创建一个实例(在 通用术语)该模板的朋友。您可以通过以下方式进行 [...]

在定义你的类之前先做一个前向声明:

template <class K, class T> class KeyedCollection;

template<class K, class T>
ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst);

因为编译器从参数列表中知道模板 参数是 T 和 U,你不必把它们放在 <...> 之间,所以 它们可以留空。

然后做你的朋友声明,并确保在operator&lt;&lt;之后添加&lt;&gt;

template <class K, class T> 
class KeyedCollection 
public:

// snip

friend ostream& operator<< <> (ostream& outstream,const KeyedCollection<K,T>& inst);

// snip

;

终于可以定义了:

template<class K, class T>
ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst) 

// Just an example
for (const auto& t : inst.objects)

    std::cout << t << std::endl;


return outstream;

Live Example


或者,按照Yakk 的建议去做。

template <class K, class T> 
class KeyedCollection 
public:

// snip

friend ostream& operator<<(ostream& outstream,const KeyedCollection<K,T>& inst) 

for (const auto& t : inst.objects)

    std::cout << t << std::endl;


return outstream;


// snip

;

Live Example

【讨论】:

这有帮助!!它实际上运行了一次,但是......它导致了堆栈溢出。您能想到这段代码中有什么会导致这种情况吗? @jordpw 嗯,我猜任何导致 *** 的原因都会出现在您的 main 代码中,因为很明显 *** 不会出现在实时示例中。 好的,我更改了部分主程序并且成功了。感谢您的帮助。

以上是关于在 ostream 重载友元函数中使用向量的主要内容,如果未能解决你的问题,请参考以下文章

模板类中的友元函数

5.友元运算符重载

从一个二级题来看成员函数重载运算符和友元函数重载运算符

为模板类重载友元运算符 <<

什么运算符一定要重载友元函数,什么时候一定要重载为成员函数?

C++运算符重载函数作为友元函数