C++模板链表实现中输入输出运算符重载友元声明语法疑问
问题1:重载>>运算符时为什么要使用template <typename U>声明友元
operator>>本身是独立于List类的模板函数,要将其声明为List类的友元,这是其中一种标准写法:
- 声明时加
template <typename U>,代表将整个operator>>模板的所有实例都声明为任意List<T>实例的友元。这里使用U作为模板参数名是为了和外层List类的模板参数T区分,避免命名冲突。 - 这种写法不需要提前前置声明
operator>>模板,实现更简单,但权限范围更宽:所有operator>>的特化版本都可以访问任意类型List实例的私有成员。
问题2:重载<<运算符的友元声明中operator<<右侧的<T>是什么含义
首先注意代码顶部有operator<<的前置模板声明:
template <typename T> ostream& operator<< (ostream&, const List<T>&);
友元声明里的<T>是模板实参指定的写法,含义是:仅将operator<<模板中,模板参数和当前List实例的参数T完全匹配的单个实例,声明为当前List<T>实例的友元。
举个实际的例子:当你实例化List<int>时,这个声明只会把ostream& operator<<(ostream&, const List<int>&)这个函数设为友元,对应List<string>等其他类型的operator<<实例,无法访问List<int>的私有成员,权限控制更严格。
补充说明:这两种友元声明写法都是合法的,你也可以将
operator>>的友元声明改成和operator<<相同的形式,提前前置声明operator>>模板后,写为friend istream& operator>> <T> (istream&, List<T>&);即可。
内容的提问来源于stack exchange,提问作者Johnny
相关产品推荐
相关产品推荐

