Aby odnieść się do operator<< <T, TSIZE>
, podobnie jak w przypadku specjalizacji szablonu, deklaracja głównego szablonu musi być widoczna. Z kolei operator<<
potrzebuje deklaracji MyTest
, ponieważ pojawia się jako parametr.
// Declare MyTest because operator<< needs it
template<class T, unsigned int TSIZE> class MyTest;
// Declare primary template
template<class T, unsigned int TSIZE>
inline std::ostream& operator<<(std::ostream& lhs, const MyText<T, TSIZE>& rhs);
template<class T, unsigned int TSIZE> class MyTest
{
// Specialization MyTest<T, TSIZE> only declares
// specialization operator<< <T, TSIZE> as friend
// Note that you can just use '<>' to designate the specialization,
// template parameters are deduced from the argument list in this case
inline friend std::ostream& operator<< <> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs);
};
Posiadana definicja powinna odpowiadać tym deklaracjom. Zauważ, że ponieważ operator<<
jest szablonem, jego definicja powinna znajdować się w nagłówku.
Alternatywą, która wymaga mniej pracy przy pisaniu wszystkich deklaracji prewencyjnych, jest dla MyTest<T, TSIZE>
zadeklarowanie całego szablonu jako przyjaciela, a nie tylko specjalizacji, która zajmuje MyTest<T, TSIZE>
.
// in MyTest definition
template<typename U, unsigned USIZE>
inline friend std::ostream& operator<<(std::ostream& lhs, const MyTest<U, USIZE>& rhs);
Definicja powinna również trzeba dopasować taką deklarację (nazwy parametrów szablonu nie ma żadnego wpływu na dopasowywaniu deklaracji i definicji).
W celu uzupełnienia, wspomnę, że jeśli chodzi o przyjaciela szablonu klasy, alternatywą jest zdefiniowanie go w definicji szablonu klasy. To definiuje funkcję znajomego, która nie jest szablonem, która jest unikalna dla każdej specjalizacji.
// in MyTest definition
friend std::ostream& operator<<(std::ostream& lhs, MyTest const& rhs)
{ /* implementation */ }
Jest niemożliwe, aby odwoływać się do takich funkcji (np &ns::operator<<
nie działa, w przeciwieństwie do innych opcji) i znajdują się one tylko przez ADL.
Co dokładnie masz na myśli przez "nie działa" ... błędy kompilatora? Jakie błędy? Najpierw przypuszczam ... "przyjaciel" nie należy do wersji .cpp. –