C++ 如何正确声明模板类的嵌套类的友元?
当我执行以下操作时:C++ 如何正确声明模板类的嵌套类的友元?,c++,templates,warnings,C++,Templates,Warnings,当我执行以下操作时: template <typename T> class Container { public: class Iterator { friend bool operator==(const Iterator& x, const Iterator& y); }; }; template <typename T> class Container_Iterator; template <typ
template <typename T>
class Container
{
public:
class Iterator
{
friend bool operator==(const Iterator& x, const Iterator& y);
};
};
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==
模板
类容器
{
公众:
类迭代器
{
友元布尔运算符==(常量迭代器&x,常量迭代器&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)
警告:朋友声明
'bool operator==(常量容器::迭代器&,
常量容器::迭代器&)'
声明一个非模板函数[-Wnon-template-friend]
友元布尔运算符==(常量迭代器&x,常量迭代器&y);
^
(如果这不是你想要的,
确保已声明函数模板
并在此处的函数名后添加)
我相当肯定这是一个新的警告,因为我一直这样做,从来没有任何问题
有人能解释一下为什么这是一个警告,以及它警告了什么吗?它警告了一个事实,即在课堂外定义
操作符==
几乎是不可能的
也就是说,friend
声明与非模板的操作符==
函数成为朋友-例如,Container::Iterator
将函数作为朋友
bool operator==(const Container<Int>::Iterator&, const Container<Int>::Iterator&);
这是一个函数模板,与友元声明不匹配。(在这种情况下,情况更糟,因为t
处于非推断上下文中,所以不能实际使用此运算符。)
警告消息建议了一种可能的修复方法-首先声明函数模板,然后对其进行专门化。(您需要将迭代器
从类中拉到它自己单独的类模板中,以便可以推导出T
。)另一种可能的解决方法是只在类模板定义中定义函数。声明
friend bool operator==(const Iterator& x, const Iterator& y);
在最近的封闭命名空间作用域中声明一个非模板函数,该函数接受两个类型为const typename Container::Iterator&
的参数。因此,每当使用一些模板参数T
实例化类容器时,就会声明一个新的操作符==
重载
由于此运算符==
不是从模板实例化的,因此不能将其定义为模板。因此,定义您声明的运算符==
的唯一方法是为实例化了容器的每个类型分别定义它。这几乎肯定是不可取的
警告警告您声明的朋友不是模板,这会产生我刚才解释过的不良后果
我认为正确的方法是:
template <typename T>
class Container
{
public:
class Iterator
{
friend bool operator==(const Iterator& x, const Iterator& y);
};
};
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==
模板
类容器迭代器;
模板布尔运算符==(常量容器迭代器&x,
常量容器(迭代器&y);
模板
类容器
{
公众:
typedef容器迭代器迭代器;
};
模板
类容器迭代器{
friend bool运算符==(常量容器迭代器&x,
常量容器(迭代器&y);
};
//顺便说一句,别忘了定义运算符==
现在,我们显式地将操作符==
声明为模板,迭代器的每个专门化都将操作符==
的相应专门化声明为它的朋友。我刚才问了一个非常类似的问题:所以您也可以帮助我。你说“定义这个操作符==的唯一方法就是为实例化容器的每个类型分别定义它。”这正是我想要做的。你知道这在我的情况下是如何工作的吗?@Mario你只需要定义一个非模板函数,并为你想要的类型提供正确的签名。但正如我所说,对于每种类型,您都需要分别执行此操作。我真的认为你不想这么做。