I have been trying all sorts of declarations but haven't got it right,getting all sorts of errors like syntax errors and linking errors. this is the last attempt that made any sense to me. what am I doing wrong?
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;
}
and the main:
int main()
{
Array<int> arr;
Array<int>::Iterator it;
it=5+it;
return 0;
}
i get this error:
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
For one thing, typename const Array<T>::Iterator
is wrong. It should be const typename Array<T>::Iterator
. Since typename
is for helping the compiler know what to do with something after a ::
, always put it immediately left of your A::B::C
-type pattern.
You can't name a specialization of a function template as a friend
before the general template has been declared. And you can't declare that template until the type Array<T>::Iterator
has been declared.
One thing you could do: Make the entire function template a friend
, not just the one specialization.
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;
}
It's a little bit sloppy in granting friend
ship, but gets the job done.
Or, if you're willing to move the definition of nested class Iterator
later in the file:
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;
}
That takes care of how to declare and define them. Unfortunately, this operator+
is not easy to use, because of the details of template argument deduction rules....
I would probably try getting around this last issue by making Iterator
a non-nested template:
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;
};