Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何正确声明模板类的嵌套类的友元?_C++_Templates_Warnings - Fatal编程技术网

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你只需要定义一个非模板函数,并为你想要的类型提供正确的签名。但正如我所说,对于每种类型,您都需要分别执行此操作。我真的认为你不想这么做。