2013-02-09 14 views
5

(sto assumendo la conoscenza del Abrahams/Dimov example in questa domanda.)funzione template specializzazione e l'esempio Abrahams/Dimov

supponga c'è qualche codice di terze parti in un colpo di testa che, come questo, che non è possibile modificare:

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) 

la domanda è:

Se mi è stato dato alle dichiarazioni di cui sopra come-è, è possibile per me ora specializzare il modello di base 1 per il caso in cui T = int * (per esempio)?

Oppure la semplice dichiarazione del modello di base 2 implica che il modello di base 1 non può più essere specializzato (almeno per i puntatori)?

+0

Anche se si potesse, sarebbe possibile chiamare quella specializzazione? Sembra che il template di base 2 sia sempre "vincente" se f viene chiamato con un puntatore. – Mat

+0

@Mat: non dall'unità di traduzione corrente, per quanto posso vedere, ma potrebbe essere richiamabile da un'altra unità di traduzione, penso, giusto? Supponendo che l'altra unità di traduzione abbia una dichiarazione non sovraccaricata di # 1 e della specializzazione corrispondente. – Mehrdad

+0

Un TU che non avrebbe il modello di base 2 in ambito? (Non sono sicuro di aver capito.) Attenti anche alle violazioni ODR. – Mat

risposta

0

Si potrebbe sempre provare e poi venire da noi. Ma non vedo perché non funzionerebbe. Se T = int* funzionerà come vuoi. E quindi no 2 sarebbe un parametro di int* *

+1

Ho rovinato l'esempio? Per me sembra che la specializzazione per 'T = int *' richiederebbe la stessa sintassi esatta di (3) ('template <> void f <> (int *);'), che quindi rende impossibile ... – Mehrdad

+0

@ Mehrdad hai ragione. non può essere fatto :) a meno che non trovi un modo per forzare un particolare sovraccarico (qualche altra differenza b/n le funzioni che puoi sfruttare) –

+0

@Mehrdad I GOT IT: puoi fare una classe con operatori '=' e conversione implicita ' 'che sono' int' ma fanno un sovraccarico della tua funzione che prende la classe stessa (quindi sceglieresti quella invece di quella int) –

2

È possibile sovraccaricare (1) specificando in modo esplicito il parametro di template nelle angolari parentesi dopo il nome della funzione (cfr 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

Corretta, sebbene non sia un "sovraccarico". È una specializzazione esplicita. – Stephen305

Problemi correlati