2013-02-09 16 views
5

(Jestem przy założeniu znajomości Abrahams/Dimov example w tej kwestii).Funkcja specjalizacja szablonu i przykład Abrahams/Dimov

Załóżmy, że jest jakiś kod 3rd-Party w nagłówku, że podoba Ci się to, co nie można modyfikować:

template<class T> void f(T); // (1) base template 1 
template<class T> void f(T *); // (2) base template 2 
template<> void f<>(int *);  // (3) specialization of (2) 

pytanie brzmi:

Gdybym nadano deklaracje powyżej jak jest to możliwe mi teraz specjalizować szablon Podstawa 1 dla przypadku gdy T = int * (na przykład)?

Czy sama deklaracja wzoru podstawowego 2 oznacza, że ​​szablon podstawowy 1 nie może być wyspecjalizowany (przynajmniej dla wskaźników)?

+0

Nawet gdybyś mógł, czy ta specjalizacja byłaby na żądanie? Wygląda na to, że szablon podstawowy 2 zawsze "wygrał", gdyby wywołano f za pomocą wskaźnika. – Mat

+0

@Mat: Nie w obecnej jednostce tłumaczeniowej, o ile widzę, ale można by ją wywołać z innej jednostki tłumaczeniowej, tak myślę, prawda? Zakładając, że druga jednostka tłumaczeniowa ma nieprzeładowaną deklarację nr 1 i odpowiadającej jej specjalizacji. – Mehrdad

+0

Jednostka tłumaczeniowa, która nie ma szablonu podstawowego 2 w zakresie? (Nie jestem pewien, czy rozumiem.) Strzeżcie się również naruszeń ODR. – Mat

Odpowiedz

0

Zawsze możesz spróbować, a następnie przyjść do nas. Ale nie rozumiem, dlaczego nie działałoby. Jeśli T = int* będzie działać tak, jak chcesz. A zatem nie ma 2 byłoby parametrem int* *

+1

Czy zepsułem przykład? Dla mnie wydaje się, że specjalizacja dla 'T = int *' wymagałaby tej samej dokładnej składni jak (3) ('template <> void f <> (int *);), co uniemożliwia ... – Mehrdad

+0

@ Mehrdad, masz rację. nie można tego zrobić :) chyba, że ​​znajdziesz sposób na wymuszenie określonego przeciążenia (inna różnica b/w funkcji, które możesz wykorzystać) –

+0

@Mehrdad I GOT IT: możesz utworzyć klasę z operatorami '=' i niejawnymi konwersjami ' 'które są' int' ale powodują przeciążenie twojej funkcji, która bierze klasę w sobie (stąd wybrałaby tę zamiast int) –

2

Można przeciążać (1), wyraźnie określając parametr szablonu w kąta nawiasie po nazwie funkcji (por C++ 11-Standard 14.7.3)

#include <iostream> 
using namespace std; 
template<class T> void f(T) // (1) base template 1 
{ 
    cout << "template<class T> void f(T)" << endl; 
} 

template<class T> void f(T *) // (2) base template 2 
{ 
    cout << "template<class T> void f(T *)" << endl; 
} 
//template<> void f<>(int *);  // (3) specialization of (2) 

template<> void f<int*>(int *)  // (4) specialization of (1) 
{ 
    cout << "f<int*>(int *)" << endl; 
} 


int main() { 
    int i; 
    f(&i); // calls (2) since only base-templates take part in overload resolution 
    return 0; 
} 
+0

Prawidłowo, chociaż nie jest to "przeciążenie". To jest wyraźna specjalizacja. – Stephen305