How to properly declare a friend of a nested class of a template class?

前端 未结 2 677
予麋鹿
予麋鹿 2020-12-19 10:54

When I do the following:

template 
class Container
{
public:
    class Iterator
    {
        friend bool operator==(const Iterator& x,         


        
2条回答
  •  独厮守ぢ
    2020-12-19 11:13

    The declaration

    friend bool operator==(const Iterator& x, const Iterator& y);
    

    declares a non-template function at the nearest enclosing namespace scope which takes two arguments of type const typename Container::Iterator&. Thus, every time the class Container is instantiated, with some template parameter T, a new overload of operator== is declared.

    Since this operator== is not instantiated from a template, you cannot define it out-of-line as a template. So the only way to define this operator== you have declared is to define it separately for each type for which Container is instantiated. This is almost certainly not desirable.

    The warning warns you that the friend you declared is not a template, which has the undesirable consequences I just explained.

    I believe the correct way to do what you are trying to do is the following:

    template 
    class Container_Iterator;
    
    template  bool operator==(const Container_Iterator& x,
                                          const Container_Iterator& y);
    
    template 
    class Container
    {
    public:
        typedef Container_Iterator Iterator;
    };
    
    template 
    class Container_Iterator {
      friend bool operator==(const Container_Iterator& x,
                                const Container_Iterator& y);
    };
    
    // btw, don't forget to define operator==
    

    Now we explicitly declare operator== as a template, and each specialization of the iterator declares the corresponding specialization of operator== as its friend.

提交回复
热议问题