2015-05-15 19 views
11

Non ho familiarità con i modelli. Ho appena iniziato ad impararlo. Perché sto ricevendo errori nel seguente programma?Errore di ambiguità di chiamata di funzione modello

#include <iostream> 
#include <string> 
using std::cout; 
using std::string; 
template<class C> 
C min(C a,C b) { 
    return a<b?a:b; 
} 
int main() 
{ 
    string a="first string"; 
    string b="second string"; 
    cout<<"minimum string is: "<<min(a,b)<<'\n'; 
    int c=3,d=5; 
    cout<<"minimum number is: "<<min(c,d)<<'\n'; 
    double e{3.3},f{6.6}; 
    cout<<"minimum number is: "<<min(e,f)<<'\n'; 
    char g{'a'},h{'b'}; 
    cout<<"minimum number is: "<<min(g,h)<<'\n'; 
    return 0; 
} 

Errori:

13 [Error] call of overloaded 'min(std::string&, std::string&)' is ambiguous 

6 [Note] C min(C, C) [with C = std::basic_string<char>] 

Ti prego, aiutami.

+1

Che compilatore stai utilizzando? Sarebbe il tuo '' ha una funzione minima definita in esso. – NathanOliver

+0

Ho rinominato la classe e viene eseguita correttamente (http://ideone.com/ygVUcr). Non sono sicuro del motivo per cui 'min' è in conflitto con' std :: min'. – Mahesh

+0

@Mahesh: hai riprodotto il problema senza rinominarlo? –

risposta

14

Ci sono due cose da fare qui.

Il tuo primo problema è che hai incluso solo parte del messaggio di errore. Here is a link to the code being complied in gcc and clang, e uno dei messaggi di errore derivanti (per intero):

main.cpp:13:34: error: call to 'min' is ambiguous 
    cout<<"minimum string is: "<<min(a,b)<<'\n'; 
           ^~~ 
/usr/include/c++/v1/algorithm:2579:1: note: candidate function [with _Tp = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >] 
min(const _Tp& __a, const _Tp& __b) 
^ 
main.cpp:6:3: note: candidate function [with C = std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >] 
C min(C a,C b) { 
^

ci sono due candidati. Uno a main.cpp:6:3 (riga 6, carattere 3) e uno a algorithm:2579:1 (riga 2579, carattere 1).

Uno di quelli che hai scritto e uno di loro in #include <algorithm>.

Uno dei file di intestazione incluso <algorithm> senza che tu lo chieda. Le intestazioni standard sono autorizzate a farlo, tanto fastidioso quanto a volte.

Nel <algorithm> è presente un modello di funzione std::min. Poiché std::string è un'istanza di una classe template in namespace std, il modello di funzione std::min si trova tramite un processo chiamato "argomento dipendente lookup" o "Koenig lookup". (i candidati con overloading delle funzioni vengono cercati localmente, e anche negli spazi dei nomi degli argomenti della funzione, e negli spazi dei nomi degli argomenti del template agli argomenti della funzione, e negli spazi dei nomi delle cose puntate dagli argomenti del funzione, ecc.)

Si trova anche la funzione locale min, poiché si trova nello stesso spazio dei nomi del corpo di main.

Entrambi sono ugualmente validi, e il compilatore non può decidere quale chiamare. Quindi genera un errore che ti dice questo.

Entrambi gcc e clang do error: quindi una sequenza di note: s. Solitamente all del note: s dopo un errore sono importanti per la comprensione dell'errore.

Per risolvere questo problema, provare a chiamare ::min (completamente qualificazione la chiamata), o rinominare la funzione di qualcos'altro, o fare la vostra versione un match migliore di std::min (difficile, ma fattibile in alcuni casi), o chiamando (min)(a,b). L'ultimo blocco ricerca ADL/Koenig e blocca anche l'espansione delle macro (ad esempio, se alcuni SO hanno iniettato macro #define min nelle intestazioni di sistema) (tramite @ 0x499602D2).

+2

Oppure do '(min) (a, b) ':) – 0x499602D2

+0

@ 0x499602D2: Grazie, funziona. Ma come funziona? Qual è il significato di (min) (a, b)? – Destructor

+1

@meet '(min)' non è un'espressione di chiamata di funzione, quindi ADL non verrà utilizzato. – 0x499602D2

5

Si sta verificando una collisione di nome con std::min. Probabilmente è incluso in uno degli altri header di liberia standard che hai incluso, sia <iostream> o <string>, la mia ipotesi è probabilmente quest'ultima. La soluzione rapida è rinominare la tua funzione. Ad esempio, rinominandolo in mymin funziona correttamente. Demo

+1

@ Ma come si verifica la collisione. Non ho scritto usando namespace std; ? – Destructor

+2

Non è necessario, dal momento che 'std :: string' è nello spazio dei nomi della libreria standard, risolverà' std :: min' tramite la ricerca dipendente dall'argomento (ADL). – CoryKramer

+0

Sembra che '' sia incluso da '' se sto leggendo l'errore qui [qui] (http://coliru.stacked-crooked.com/a/189c75cb32ed7b58) – NathanOliver

Problemi correlati