如何声明一个接受模板类嵌套类的全局友元函数

how to declare a global friend function that takes an nested class of a template class?

本文关键字:嵌套 全局 函数 友元 声明 何声明 一个      更新时间:2023-10-16

我一直在尝试各种声明,但没有得到它的权利,得到各种错误,如语法错误和链接错误。这是我最后一次有意义的尝试。我做错了什么?

template<class T>
class Array
{
public:
  class Iterator
  {
  public:
    friend Iterator operator+<>(const int,typename const Array<T>::Iterator&);
  };
};
template <class T>
typename Array<T>::Iterator operator+(const int,typename const Array<T>::Iterator& it)
{
    return it;
}

和主:

int main()
{
  Array<int> arr;
  Array<int>::Iterator it;
  it=5+it;
  return 0;
}

我得到这个错误:

 error C2785: 'Array<T>::Iterator operator +(const int,const Array<T>::Iterator &)' and 'Array<T>::Iterator +(const int,const Array<T>::Iterator &)' have different return types

首先,typename const Array<T>::Iterator是错误的。应该是const typename Array<T>::Iterator。因为typename是为了帮助编译器知道如何处理::之后的东西,所以总是把它放在你的A::B::C类型模式的左边。

在声明通用模板之前,不能将函数模板的特化命名为friend。在声明了Array<T>::Iterator类型之前,不能声明该模板。

你可以做的一件事是:使整个函数模板都是friend,而不仅仅是一个专门化。

template<class T>
class Array
{
public:
    class Iterator
    {
    public:
        template <class U> friend
        typename Array<U>::Iterator operator+(
            const int, const typename Array<U>::Iterator&);
    };
};
template <class T>
typename Array<T>::Iterator operator+(
    const int, const typename Array<T>::Iterator& it)
{
    return it;
}

授予friend ship有点草率,但还是完成了任务。

或者,如果您愿意将嵌套类Iterator的定义移到文件的后面:

template<class T>
class Array
{
public:
    class Iterator;
};
template <class T>
typename Array<T>::Iterator operator+(
    const int, const typename Array<T>::Iterator& it);
template <class T>
class Array<T>::Iterator
{
public:
    friend Iterator operator+<T>(const int, const Iterator&);
};
template <class T>
typename Array<T>::Iterator operator+(
    const int, const typename Array<T>::Iterator& it)
{
    return it;
}

负责如何声明和定义它们。不幸的是,这个operator+并不容易使用,因为模板参数演绎规则的细节....

我可能会尝试通过使Iterator成为非嵌套模板来解决最后一个问题:

namespace Array_detail {
    template <class T> class Array_Iterator;
    template <class T>
    Array_Iterator<T> operator+(int, const Array_Iterator<T>&);
    template <class T>
    class Array_Iterator {
        friend Array_Iterator operator+<>(int, const Array_Iterator&);
    };
}
template <class T>
class Array {
public:
    typedef Array_detail::Array_Iterator<T> Iterator;
};