如何正确声明模板类的嵌套类的友元
How to properly declare a friend of a nested class of a template class?
>当我执行以下操作时:
template <typename T>
class Container
{
public:
class Iterator
{
friend bool operator==(const Iterator& x, const Iterator& y);
};
};
GCC给了我以下警告和建议:
warning: friend declaration
'bool operator==(const Container<T>::Iterator&,
const Container<T>::Iterator&)'
declares a non-template function [-Wnon-template-friend]
friend bool operator==(const Iterator& x, const Iterator& y);
^
(if this is not what you intended,
make sure the function template has already been declared
and add <> after the function name here)
我相当确定这是一个新的警告,因为我总是这样做,从来没有遇到任何问题。
有人可以解释为什么这是一个警告,以及它警告什么吗?
警告说,几乎不可能将这种operator==
定义为类外的。
也就是说,friend
声明与非模板operator==
函数交朋友 - 例如,Container<Int>::Iterator
将函数作为友元
bool operator==(const Container<Int>::Iterator&, const Container<Int>::Iterator&);
此函数不是模板,因此几乎无法为类模板定义之外的所有可能Container
定义operator==
。
如果你尝试做
template<class T>
bool operator==(const Container<T>::Iterator&, const Container<T>::Iterator&);
这是一个函数模板,与好友声明不匹配。(在这种情况下,情况更糟,因为您实际上无法使用此运算符,因为T
处于非推导上下文中。
警告消息建议了一种可能的解决方法 - 首先声明函数模板,然后与它的专用化交朋友。(您需要将Iterator
从类中提取到其自己的单独类模板中,以便可以推断出T
。另一个可能的解决方法是只在类模板定义中定义函数。
声明
friend bool operator==(const Iterator& x, const Iterator& y);
在最近的封闭命名空间作用域声明一个非模板函数,该函数采用两个类型为 const typename Container<T>::Iterator&
的参数。因此,每次实例化类Container
时,都会使用一些模板参数T
,声明一个新的重载 operator==
。
由于此operator==
不是从模板实例化的,因此不能将其外联定义为模板。因此,定义已声明的此operator==
的唯一方法是为实例化Container
的每个类型单独定义它。这几乎肯定是不可取的。
您声明的朋友不是模板,这会产生我刚才解释的不良后果。
我相信做你想做的事情的正确方法是:
template <typename T>
class Container_Iterator;
template <typename T> bool operator==(const Container_Iterator<T>& x,
const Container_Iterator<T>& y);
template <typename T>
class Container
{
public:
typedef Container_Iterator<T> Iterator;
};
template <typename T>
class Container_Iterator {
friend bool operator==<T>(const Container_Iterator<T>& x,
const Container_Iterator<T>& y);
};
// btw, don't forget to define operator==
现在我们显式声明operator==
为模板,迭代器的每个专用化都将operator==
的相应专用化声明为其友元。
- 如何在嵌套类中正确使用友元声明?
- 在为嵌套类定义行外友元时,我真的必须打破封装吗?
- 筛选嵌套的动态元组(元组的动态元组)
- 以嵌套类为参数的友元模板声明
- 模板化类的嵌套类中的友元运算符
- 使用标准库在 c++11 中使用 std::tie 提取嵌套在元组中的元组
- 嵌套友元类所需的前向声明
- const_iterator:嵌套类还是友语类?
- 如何使用来自友元函数的嵌套类?
- 为什么 Visual C++无法编译从私有嵌套类继承的友元模板
- 嵌套异常和基元类型
- 如何正确声明模板类的嵌套类的友元
- 友元类如何访问嵌套类的私有成员
- 嵌套类中需要前向声明的友元声明
- C++:特定于友元的对象(嵌套类)
- 私有嵌套类中的友元
- 如何声明一个接受模板类嵌套类的全局友元函数
- 友元方法不能访问嵌套类
- 具有嵌套命名空间内的友元函数的模板类
- 带有友元运算符的模板类的嵌套类,编译错误