Во-первых, вперед объявите класс Matrix. Это позволяет классу Iterator видеть имя класса Matrix, а также создавать указатели и ссылки на него. (Он не позволяет классу Iterator получать доступ к данным-членам или вызывать функции-члены.)
template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix;
Затем определите класс Iterator. Все, что он может сделать на этом этапе - это хранить ссылки и указатели на Матрицу. (Нет доступа к членам Matrix.)
template<typename T, typename Size>
class Iterator{
// don't define any function bodies in here
//but do put all data members and prototypes in here
};
Затем определите класс Matrix (который может получить доступ к членам Iterator)
template<typename T, typename Size, typename Stack, typename Sparse>
class Matrix{
// don't define any function bodies in here
//but do put all data members and prototypes in here
};
Затем определите тела методов для каждого класса. На этом этапе методы обоих классов могут получить доступ к членам друг друга. Обычно эта часть находится в файле .cpp, но для шаблонов она принадлежит файлу .h.
template<typename T, typename Size, typename Stack, typename Sparse>
Matrix<T,Size,Stack,Sparse>::Matrix(){ /*...*/}
template<typename T, typename Size>
Iterator<T,Size>::Iterator(){ /*...*/ }