Самое простое, что нужно сделать, это оставить print
общедоступным (как в вашем примере), чтобы оператору не нужно было дружить.
template <class T>
class MyTemp {
public:
void print(std::ostream& os, char ofc = ' ') const;
};
template <class T>
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) {
a.print(os);
return os;
}
Если вам нужно, чтобы он был закрытым, тогда вам нужно объявить правильную специализацию шаблона как друга - ваше объявление friend
объявляет не шаблонный оператор в окружающем пространстве имен, а не шаблон. К сожалению, чтобы сделать шаблон друга, вам необходимо объявить его заранее:
// Declare the templates first
template <class T> class MyTemp;
template <class T> std::ostream& operator<< (std::ostream&, const MyTemp<T>&);
template <class T>
class MyTemp {
public:
friend std::ostream& operator<< <>(std::ostream& os, const MyTemp<T>& a);
// With a template thingy here ^^
private:
void print(std::ostream& os, char ofc = ' ') const;
};
template <class T>
std::ostream& operator<< (std::ostream& os, const MyTemp<T>& a) {
a.print(os);
return os;
}
Или вы можете определить оператор inline:
template <class T>
class MyTemp {
public:
friend std::ostream& operator<<(std::ostream& os, const MyTemp<T>& a) {
a.print(os);
return os;
}
private:
void print(std::ostream& os, char ofc = ' ') const;
};
Ваш последний вопрос:
Во-вторых, как только это будет исправлено, я просто вызову a.print(os)
внутри <<
перегрузки? Я знаю, что для этого нужно вернуть ostream
.
Он действительно должен возвращать ostream
- просто верните тот, который был передан, как в моем примере кода.