2012-07-30 19 views
5

Co to jest poprawny sposób zadeklarować funkcję przyjaciel klasy szablonu (dla std :: ostream & operator < <) w pliku .cpp?C++: przyjaciel funkcji w klasie szablonu dla operatora <<

Moja obecna implementacja nie działa:

// MyTest.h 
template<class T, unsigned int TSIZE> class MyTest 
{ 
    inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs); 
}; 

// MyTest.cpp 
template<class T, unsigned int TSIZE> inline friend std::ostream& operator<< <T, TSIZE> (std::ostream &lhs, const MyTest<T, TSIZE> &rhs) 
{ 
    // IMPLEMENTATION 
} 

Dziękuję bardzo!

+0

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. –

Odpowiedz

7

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.

0

Nie jest do końca jasne, co pierwotnie post chciał. Zakładam, że będzie on chciał następujące:

// Some template class. 
template<class T, unsigned int TSIZE> class MyTest { }; 

// Some template function. 
template<class T, unsigned int TSIZE> std::ostream& operator<< (std::ostream &lhs, const MyTest<T, TSIZE> &rhs) 
{ 
    // IMPLEMENTATION 
} 

Teraz konieczne jest stwierdzenie tej funkcji szablonu jako znajomego klasy, ponieważ ta funkcja wymaga dostępu do chronionych obiektów My test. Można to osiągnąć z następującą definicją:

template<class T, unsigned int TSIZE> class MyTest 
{ 
    template<class T1, unsigned int TSIZE1> 
    friend std::ostream& operator<< (std::ostream &lhs, const MyTest<T1, TSIZE1> &rhs); 
}; 

Szablon nagłówka jest potrzebne przed deklaracją friend ponieważ jest to funkcja związana szablon, który nie należy do bieżącej klasy szablonu.

Powiązane problemy