Мой шаблонный класс выглядит так:
template<unsigned WIDTH, unsigned HEIGTH, typename T = int> class matrix { ... }
Простые и понятные аргументы шаблона определяют размер матрицы. Размер логически постоянен, поэтому я реализовал его так, чтобы он был согласованным. Но когда я пытаюсь написать функцию, которая принимает мой matrix
Я сталкиваюсь со следующей проблемой:
std::ostream& operator<<(std::ostream &os, const matrix &m){ ...}
Написанный так, компилятор справедливо возражает против отсутствия аргументов шаблона … Но
std::ostream& operator<<(std::ostream &os, const matrix<unsigned, unsigned> &m){ ...}
вызывает эту ошибку: error: expected a constant of type 'unsigned int', got 'unsigned> int'
Что также отчасти верно, так как matrix
ожидает константы, а не типы.
Как с этим бороться? Я уверен, что я не первый, кто сталкивается с этой проблемой, каков наиболее «канонический» способ решения этой проблемы передачи константно-параметризованных шаблонов?
Объявить operator<<
как друг функция в рамках matrix
учебный класс:
template<unsigned WIDTH, unsigned HEIGTH, typename T = int>
class matrix
{
friend std::ostream& operator<<(std::ostream &os, const matrix& m)
// ^^^^^^ plain name
{
return os;
}
};
Делать operator<<
также шаблон функции:
template<unsigned WIDTH, unsigned HEIGHT, typename T>
std::ostream& operator<<(std::ostream &os, const matrix<WIDTH, HEIGHT, T>& m)
// ^^^^^ ^^^^^^ ^
{
return os;
}
Объявите свой operator<<(ostream&)
перегрузка для вашего шаблона класса matrix
в качестве шаблона, который должен быть очевидным решением здесь
template<unsigned WIDTH, unsigned HEIGTH, typename T = int>
class matrix
{
public:
T arr[WIDTH][HEIGTH];
};
template<unsigned WIDTH, unsigned HEIGTH, typename T>
std::ostream& operator<<(std::ostream &os, const matrix<WIDTH, HEIGTH,T> &m)
{
// formatting inserter of m onto os
return os;
}
int main()
{
matrix<10, 10> m;
std::cout << m << std::endl;
}
Но, вообще говоря, если ваш operator<<(ostream&)
нужен доступ к вашим личным данным (что обычно бывает), вы в конечном итоге объявите их как друзей. Если вы не хотите повторять параметры remplate, поместите operator<<(ostream&)
не являющийся членом в рамках вашей матрицы класса
template<unsigned WIDTH, unsigned HEIGTH, typename T = int>
class matrix
{
T arr[WIDTH][HEIGTH];
friend std::ostream& operator<<(std::ostream &os, const matrix &m)
{
// formatting inserter of m onto os
return os;
}
};
перегруженный operator<<
также должен быть шаблон:
template<unsigned WIDTH, unsigned HEIGHT, typename T>
std::ostream& operator<<(std::ostream &os, const matrix<WIDTH, HEIGHT, T> &m){
// ...
return os;
}