Использование оператора потока с шаблоном класса

Я создаю матричный класс и имею следующую декларацию. Намерение состоит в том, чтобы создать масштабируемый матричный класс, который имеет гибкие алгоритмы и может работать на различных платформах —

template<typename T> class xss_matrix{

public:
xss_matrix(int i=0, int j=0):
max_row(i), max_col(j)
{

/*create space for the (0,0) entry*/
matrix[0]= (T*)(malloc(sizeof(T)));};
~xss_matrix()
{
};
void add_entry(int row, int col, T val);
T get_entry(int row, int col);friend ostream& operator<<(ostream &out, const xss_matrix<T> &m_xss_matrix);

private:
/*Internal variables*/
int max_row, max_col;

/*Internal data structures*/
T* matrix[];/*Internal methods*/
void add_columns(int row, int col);
void add_rows(int row, int col);};

#endif

тогда я перегружаю оператор потока —

/*Overloaded stream operators*/
template<typename T> std::ostream& operator<<(ostream &out, const xss_matrix<T> &m_xss_matrix)
{

for(int ii = 0; ii < m_xss_matrix.max_row+1; ii+=1){
for(int jj = 0; jj < m_xss_matrix.max_col+1; jj+=1){
std::cout <m_xss_matrix.matrix[ii][jj] << " ";
}
std::cout << std::endl;
}

}

но когда я запускаю это —

#include "xss_matrix.hpp"
int main(int argc, char** argv)
{

xss_matrix<double>* foo = new xss_matrix<double>;
xss_matrix<double> bar;

foo->add_entry(0,0,2.35);
foo->add_entry(0,1,1.75);
foo->add_entry(1,0,1.50);
foo->add_entry(1,1,2.00);std::cout << *foo;}

Я получаю ошибку компоновщика —

[mitra@vlch-mitra xss_src]$ make
g++ -c -o main.o main.cpp -g -I. -fpermissive
In file included from xss_matrix.hpp:1,
from main.cpp:1:
xss_matrix.h:36: warning: friend declaration `std::ostream& operator<<(std::ostream&, const xss_matrix<T>&)' declares a non-template function
xss_matrix.h:36: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)
g++ -o main main.o -g -I. -fpermissive
main.o: In function `main':
/home/mitra/dv/libparser/xss_src/main.cpp:15: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, xss_matrix<double> const&)'
collect2: ld returned 1 exit status
make: *** [main] Error 1
[mitra@vlch-mitra xss_src]$

Я не понимаю предупреждение компилятора, которое, я уверен, вызывает сбой компоновщика. Может кто-нибудь помочь? Версия gcc — 4.4.7-4.
Спасибо,
Радж

0

Решение

Объявление друга объявляет не шаблонную функцию с именем operator<<; каждый экземпляр xss_matrix штампы новой декларации. Ни одна из этих функций на самом деле не определена.

Затем есть единственное определение шаблона функции, перегружающее все эти объявления. Это не объявлено другом.

Однако при разрешении перегрузки выигрывают не шаблонные перегрузки, при прочих равных условиях. Таким образом, компилятор выбирает один из них. Но это никогда не определяется, поэтому компоновщик жалуется.

Если вы действительно хотите подружиться с шаблоном, это должно быть сделано следующим образом:

template<typename T> class xss_matrix;

template<typename T>
std::ostream& operator<<(ostream &out, const xss_matrix<T>& m_xss_matrix);

template<typename T> class xss_matrix {
// Implementation here
template <typename U>
friend std::ostream& operator<<(ostream &out, const xss_matrix<U>& m_xss_matrix);
};

template<typename T>
std::ostream& operator<<(ostream &out, const xss_matrix<T> &m_xss_matrix) {
// Implementation here
}

Однако обычно проще иметь шаблон функции, не являющейся другом, просто делегировать публичную функцию-член:

template<typename T> class xss_matrix {
public:
void print(ostream& out) {
// Write data to out
}
};

template<typename T>
std::ostream& operator<<(ostream &out, const xss_matrix<T> &m_xss_matrix) {
m_xss_matrix.print(out);
return out;
}
2

Другие решения

Правильное объявление friend Функциональный шаблон:

template<class U>
friend ostream& operator<<(ostream &out, const xss_matrix<U> &m_xss_matrix);

Распределение памяти для T* matrix[]; это неверно. замещать T* matrix[]; с std::vector<T> matrix;, Это также автоматически исправляет все сгенерированные компилятором конструкторы / назначения копирования / перемещения и деструктор (вы можете удалить свой). Индексирование по строке и столбцу matrix[row * max_col + col],

1

По вопросам рекламы [email protected]