一、问题:
今天在实现 vector 时,发现出现了一个错误:

它说,不认识 ostream,我在重载<< 符号时,使用了 ostream,而且头文件 <ostream> 也包含了,std 的作用域限定符也写了,它怎么会不认识 ostream 呢,也不是不认识,编译的时候是认识的,但链接的时候出错了,真是奇怪了???
下面是代码:
#pragma once
#include<iostream>
#include<ostream>
#include<cstdlib>
namespace zzz
{
template<class T>
class vector
{
public:
typedef T* iterator;
typedef const T* const_iterator;
friend std::ostream& operator <<(std::ostream& out, const vector<T>& v);
...
... //中间是实现的各个成员函数
private:
iterator _begin = nullptr;
iterator _finish = nullptr;
iterator _endofstorage = nullptr;
};
template <class T>
std::ostream& operator << (std::ostream& out, const vector<T>& v)
{
for (auto& e : v)
{
out << e << " ";
}
return out;
}
}
二、解决:
1. 问题
其实,问题在这里:
friend std::ostream& operator <<(std::ostream& out, const vector<T>& v);
//
//
template <class T>
std::ostream& operator << (std::ostream& out, const vector<T>& v)
{
for (auto& e : v)
{
out << e << " ";
}
return out;
}
大家有看出问题吗?
是类内声明友元的时候,没有 template <class T> 的声明。

添加上 template<class T> 之后,程序就可以正常的运行了。
但是,定义 vector 类的时候,不是有声明 T 模板类型吗,为什么这里不能用类的 template 声明,而要再写一遍?

2. 解释
一次 template 可以控制的范围,我总结为:物理范围+逻辑范围。
① 类模板
类模板托管写在类内的属于类的成员:

-
写在类外的成员函数
当类模板的成员函数写在类外时,每个成员函数都要单独写template(不知道大家知不知道这一点),如下:

其实此时的成员函数已经超出类的template声明的范围了,我们大概可以这样理解:

-
友元函数
对于友元,它根本不属于类,所以不能使用人家类的template声明,而你自己又是一个函数模板,所以自然要自己声明了:

当在类内声明友元时,即使声明的代码没有用到模板类型(T),也要声明template,如果不声明template,它会认为是一个普通函数,而函数定义处,定义的是一个函数模板,两个对不上,会报错:

② 函数模板
函数模板托管的就是下面紧接着的一个函数:
普通的函数模板没什么要说的,但关于成员函数成为了一个函数模板,还是有必要提一下的:

所以,我们可以看到,类模板的成员函数本身是普通函数,但也是可以成为函数模板的,一旦成为函数模板,那使用的时候就要注意一下了。
本文到这里就结束了,如果对您有帮助,希望得到您的一个赞!🌷
如果有哪里有问题,希望大家评论指出或跟我讨论,感谢大家!
祝大家每天进步!😄
1133

被折叠的 条评论
为什么被折叠?



