2012-04-25 9 views
5

non riesco a capire perché il seguente codice compila bene:C++ instantiaion funzione template con i parametri impliciti

#include <iostream>                 

void bar(int x) {                 
    std::cout << "int " << x << std::endl;            
}                     

void bar(double x) {                 
    std::cout << "double " << x << std::endl;           
}                     

template <typename A, typename B> // Note the order of A and B.            
void foo(B x) {                  
    bar((A)x);                   
}                     

int main() {                   
    int x = 1;                   
    double y = 2;                  

    foo<int>(x);  // Compiles OK.                
    foo<double>(y);  // Compiles OK.            

    return 0;                   
} 

Ma se passo l'ordine di A e B come qui di seguito, allora non si compila:

#include <iostream>                 

void bar(int x) {                 
    std::cout << "int " << x << std::endl;            
}                     

void bar(double x) {                 
    std::cout << "double " << x << std::endl;           
}                     

template <typename B, typename A> // Order of A and B are switched. 
void foo(B x) {                  
    bar((A)x);                   
}                     

int main() {                   
    int x = 1;                   
    double y = 2;                  

    foo<int>(x);  // error: no matching function for call to ‘foo(int&)’ 
    foo<double>(y);  // error: no matching function for call to ‘foo(double&)’                

    return 0;                   
}  

EDIT: spiegazioni ad hoc sono i benvenuti, ma sarebbe meglio se qualcuno può indicare esattamente ciò che le specifiche. dice. Grazie!

+1

Il compilatore può dedurre il tipo di B nel primo esempio dal parametro passato al costruttore foo (di tipo B). Nel secondo esempio, non è possibile eseguire tale inferenza, poiché il parametro del modello fornito è B, così come il parametro del costruttore. Il tipo di A non è in nessun posto in evidenza. – Stabledog

risposta

7

Nella prima, il compilatore sa che A è int perché specificamente dite così con foo<int>, e sa che B è anche int a causa del parametro che si passa. Quindi sia A sia B sono noti o deducibili (si potrebbe dire: A è fornito, B è implicito).

Tuttavia, nella seconda, poiché B viene prima e A non compare nell'elenco dei parametri, il compilatore non può dire cosa sia A e ti dà un errore. Stai dicendo esplicitamente cosa è B con foo<int>, e quindi il parametro che passi è anche un B che, alla chiamata, è unche concorda con la tua precedente definizione esplicita di B, ma non viene fatto alcun riferimento a A, implicitamente o esplicitamente, quindi il compilatore deve fermarsi e l'errore.

Non hai davvero bisogno dello standard per questo, è solo buon senso. Cosa diavolo sarebbe A essere nel secondo?

Grazie per avermi fatto questa domanda, perché non mi ero reso conto che potevi specificare esplicitamente alcuni parametri e specificare implicitamente altri nella lista dei parametri prima di questo.

+0

Quindi, questa diventa una domanda su cosa specifica. dice riguardo a come sono determinati 'A' e' B'. Il compilatore avrebbe potuto determinare 'B' a causa dell'argomento di input, quindi calcolare' A' da 'foo '. Quindi, entrambi i parametri del modello sono determinati anche nel secondo caso. – kirakun

+1

@Kirakun non proprio. 'A' e' B' possono essere determinati solo se si specifica un tipo in '<>', o tutti quelli che non sono specificati in '<>' sono nella lista parametri, quindi il compilatore può dedurre digita dalla chiamata. Nella seconda, 'A' non è esplicitamente specificato in' <> 'e non si trova nell'elenco dei parametri, quindi non può essere conosciuto. –

+1

@Kirakun solo perché ne hai inserito uno nella lista dei parametri non significa che è saltato quando inizi a mettere le cose tra il '<>'. Sono ancora nell'ordine in cui sono nella lista 'template ', quindi 'B' è il primo, e quindi' A' secondo, sempre, indipendentemente dagli argomenti che la funzione assume. –

Problemi correlati