一つにtypename const Array<T>::Iterator
は、間違っています。である必要がありますconst typename Array<T>::Iterator
。typename
は、コンパイラが の後の何かをどうするかを知るのを助けるためのものなので、常に-type パターン::
のすぐ左に置きます。A::B::C
friend
一般的なテンプレートが宣言される前に、関数テンプレートの特殊化を として指定することはできません。Array<T>::Iterator
また、型が宣言されるまで、そのテンプレートを宣言することはできません。
friend
できることの 1 つは、1 つの特殊化だけでなく、関数テンプレート全体を aにすることです。
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
が、仕事は完了します。
または、ネストされたクラスの定義を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;
};