2012-08-08 16 views
5

C++ sss 35,16Neden arkadaş üyesi işlevi otomatik olarak işlev şablonu olarak tanınmıyor?

http://www.parashift.com/c++-faq-lite/template-friends.html

#include <iostream> 

template<typename T> 
class Foo { 
public: 
    Foo(T const& value = T()); 
    friend Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs); 
    friend std::ostream& operator<< (std::ostream& o, const Foo<T>& x); 
private: 
    T value_; 
}; 

Yazar istemlerde:

'derleyici uygun sınıf tanımında yol kadar Arkadaş hatları gördüğünde engel olur

. O anda, arkadaş fonksiyonlarının kendileri olduğunu bilmiyoruz. (neden bu? Sınıf şablonu üyesi fonksiyonlar varsayılan olarak fonksiyon şablonu değil midir?); onlar böyle olmayan şablonları olan varsayar:
Foo<int> operator+ (const Foo<int>& lhs, const Foo<int>& rhs) 
{ ... } 

std::ostream& operator<< (std::ostream& o, const Foo<int>& x) 
{ ... } 

Neden yukarıdaki olmayan şablonlar' vardır? int aracılığıyla başlatılan bu şablonlar değil mi?

'Eğer operatör + veya operatör < < işlevleri aradığınızda, bu varsayım şablon olmayan fonksiyonları için bir çağrı oluşturmak derleyici neden olur, ama aslında tanımlanmış çünkü hiçbir zaman bağlayıcı size bir 'tanımlanmamış harici' hatası verecektir bu şablon dışı işlevler. '

Aslında, derleyici fonksiyonu şablon olarak yukarıda tanımasını sağlama, programcı aşağıdaki gibi açıkça, bunu yapmak zorunda:

template<typename T> class Foo; // pre-declare the template class itself 
template<typename T> Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs); 
template<typename T> std::ostream& operator<< (std::ostream& o, const Foo<T>& x); 

kimse açıklayabilir misiniz? Ben bu oldukça sinir bozucu bulmak ve derleyici neden sadece 'int' ile T değiştirerek bir sınıf Foo örneğini başlatmak değil ve bir gün olarak adlandırmak bilmiyorum.

Teşekkürler.

cevap

5

Sınıf şablonu üyesi işlevleri şablonun bir parçasıdır ve bu nedenle şablonla örneklendirilir, ancak arkadaşlar değildir. şablon olmayan durum düşünün:

struct S { 
    friend void foo(S); 
}; 

void foo(S) bu noktada ilan edilecek yok Not; friend bildirimi, void foo(S) tanımlanmışsa bildiriyorsa, bu işlev S'a erişebilir. Asla tanımlanamayabilir ve bu iyi. Şablonlarla

durum aynıdır:

template<typename T> struct S { 
    friend void foo(S); 
}; 

Bu fonksiyon void foo(S<T>) sonra tanımlanması durumunda herhangi bir tür T, için bu işlevi S<T> erişimi olduğunu söylüyor. Bu işlev aşırı yükleyerek, somut bir işlevi olması beklenmektedir:

void foo(S<char>) { } 
void foo(S<int>) { } 

derleyici tüm T için kullanılabilecek bir işlev şablonu tedarik sonradan planlıyoruz olduğunu bilmiyor. Bunun yerine, uygun bir işlev şablonu zaten bildirilmişse, açılı ayraçlar ekleyerek bunu belirtmeniz gerekiyorsa, örneklendirilir.

Şablonu neden bildirmek zorunda olduğunuza ilişkin olarak, "şablonun" yalnızca bir deklarasyona sahip olması için bir neden yoktur.Düşünün:

#include <iostream> 
template<typename T> struct S; 
template<typename T> void foo(S<T>); 
template<typename T> void foo(S<T *>); 
template<typename T> struct S { 
    friend void foo<>(S); 
}; 
template<typename T> void foo(S<T>) { std::cout << "template template friend\n"; } 
template<typename T> void foo(S<T *>) { std::cout << "template specialization template friend\n"; } 
template void foo(S<void *>); 
int main() { 
    foo(S<int>()); 
    foo(S<void *>()); 
} 

İşte foo iki uzmanlık vardır ve bunlar friend aralarında seçmek, böylece hem ileri bildirilmesi gerekmektedir.

+0

Bazıları anlıyorum ama hepsi değil. 'Arkadaş Foo operatörü + (const Foo& lhs, const Foo & rhs);' ile birlikte, derleyici işlevin + Foo'nun bir arkadaş işlevi olacağını ve derleme türüne, işlev parametresine vb. operatör + beyanı bulunur? derleyici halinde, tanımlanmış ise operatör + (const Foo ve sol eksen, const Foo & rhs); 'ek olarak. arkadaş olacak Foo' bu, herhangi bir 'T için, görür – user1559625

+0

@ user1559625 Uygun bir şablon zaten bildirilmişse, o zaman örneklenecektir. – ecatmur

+0

Düzeltme; sözdizimi, örnekleme için bir şablon belirtmek için farklıdır (ekstra açılı ayraçlar). – ecatmur

İlgili konular