2009-06-02 9 views
30

:İşlev şablonu uzmanlık biçimi aşağıdaki fonksiyon şablonunda ikinci parantez <> sebebi nedir

template<> void doh::operator()<>(int i) 

Bu SO question gündeme geldiği bu operator() sonra, ancak elimden kayıp parantez olduğu öne sürüldü açıklama bulamıyor. fonksiyon şablonları Ancak

template< typename A > struct AA {}; 
template<> struct AA<int> {};   // hope this is correct, specialize for int 

:

Ben formun bir tür uzmanlık (tam uzmanlık) ise anlamını anlamak

bu scenarion içine bu uyum yapar
template< typename A > void f(A); 
template< typename A > void f(A*); // overload of the above for pointers 
template<> void f<int>(int);   // full specialization for int 

?:

template<> void doh::operator()<>(bool b) {} 

Çalıştığınız gibi görünen ve herhangi bir wa vermeyen örnek kod rnings/hatası (kullanılan gcc 3.3.3):

#include <iostream> 
using namespace std; 

struct doh 
{ 
    void operator()(bool b) 
    { 
     cout << "operator()(bool b)" << endl; 
    } 

    template< typename T > void operator()(T t) 
    { 
     cout << "template <typename T> void operator()(T t)" << endl; 
    } 
}; 
// note can't specialize inline, have to declare outside of the class body 
template<> void doh::operator()(int i) 
{ 
    cout << "template <> void operator()(int i)" << endl; 
} 
template<> void doh::operator()(bool b) 
{ 
    cout << "template <> void operator()(bool b)" << endl; 
} 

int main() 
{ 
    doh d; 
    int i; 
    bool b; 
    d(b); 
    d(i); 
} 

Çıktı:

operator()(bool b) 
template <> void operator()(int i) 
+0

çok gariptir. Normalde operatörü gördüm (bool b), fakat operatör() (bool b) nasıl çalışır? İlk boş() kullanımı nedir? – Jimm

+1

@Jimm yöntem adı 'operator()' dır ve bir parametre 'bool b' alır ... işlev çağrısı operatörüdür. Kod örneğimde 'ana ',' d (b) ' – stefanB

cevap

31

ben baktım ve 14.5.2/2 tarafından belirtilen tespit ettik:

A local class shall not have member templates. Access control rules (clause 11) apply to member template names. A destructor shall not be a member template. A normal (non-template) member function with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied.

ve bir örnek verilmektedir:

template <class T> struct A { 
    void f(int); 
    template <class T2> void f(T2); 
}; 

template <> void A<int>::f(int) { } // non-template member 
template <> template <> void A<int>::f<>(int) { } // template member 

int main() 
{ 
    A<char> ac; 
    ac.f(1); //non-template 
    ac.f(’c’); //template 
    ac.f<>(1); //template 
} 

Not S olduğu tandard terimleri, specialization, açık bir uzmanlık kullanarak ve kullandığınız işlev kullanılarak oluşturulan işleve işaret eder; bu durumda, oluşturulan bir uzmanlık ile yapmak zorundayız. specialization sadece, yalnızca çoğunlukla kullanıldığı bir şablonu açıkça uzmanlaştırarak oluşturduğunuz işlevleri ifade etmez. Sonuç: GCC yanlış algılamıştır. o kokan beri, (sadece bool için) int için şablonun uzmanlık şikayetçi olmadığını

"ComeauTest.c" , line 16: error: "void doh::operator()(bool)" is not an entity that can be explicitly specialized template<> void doh::operator()(bool i)

Not: ben de kod test hangi Comeau, doğru alır ve bir tanılama sorunları t aynı adla ve türüne bakın: Uzmanlığın alacağı işlev türü, olmalıdır; bu, şablon olmayan üye işlevinin işlev türünden farklıdır; bu, void(bool). Yukarıdaki çift parantez sözdizimi

+0

görüyorum. Eğer doğru bir şekilde takip ettiysem, yukarıdaki' şablon üyesi '," int için struct A uzmanlığı "nda templated bir üyedir. Şimdi mantıklı olun, bu nedenle ac.f() işlevi, parametre veya açık şablon parametre listesine (doğru ad ne olursa olsun) dayalı olarak kendi şablon çözünürlüğünü yapar. – stefanB

+1

Evet, f için sunduğumuz açık uzmanlık, int için struct A'nın uzmanlaşması içindir. genel taban şablonu f'nin tüm uzmanlıkları için var.Bu nedenle, A numaralı telefondan da ana telefon hattında olduğu gibi bunu da söyleyebiliriz (ancak bu, sadece A :: f için geçerlidir!). Evet ac.f (stuff), gerçekten kendi çözümünü yapar. Burada, 14.8.1/2'ye ("çıkarılabilir şablon argümanları ...") başvurun. Umarım bu yardımcı olur :) –

+0

Evet harika, araştırma için teşekkürler :) – stefanB