programma minimo:Sovraccarico di funzioni modello con firme identiche, perché funziona?
#include <stdio.h>
#include <type_traits>
template<typename S, typename T>
int foo(typename T::type s) {
return 1;
}
template<typename S, typename T>
int foo(S s) {
return 2;
}
int main(int argc, char* argv[]) {
int x = 3;
printf("%d\n", foo<int, std::enable_if<true, int>>(x));
return 0;
}
uscita:
1
Perché non questo invia un errore di compilazione? Quando viene generato il codice modello, le funzioni int foo(typename T::type search)
e int foo(S& search)
non hanno la stessa firma?
Se si cambia la funzione di modello di firme un po ', funziona ancora (come ci si aspetta dato l'esempio di cui sopra):
template<typename S, typename T>
void foo(typename T::type s) {
printf("a\n");
}
template<typename S, typename T>
void foo(S s) {
printf("b\n");
}
Tuttavia questo non e tuttavia l'unica differenza è che uno ha una firma int e l'altra è definita dal primo parametro template.
template<typename S, typename T>
void foo(typename T::type s) {
printf("a\n");
}
template<typename S, typename T>
void foo(int s) {
printf("b\n");
}
errore del compilatore (Clang):
test.cpp:26:2: error: call to 'foo' is ambiguous
foo<std::enable_if<true, int>>(3);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:16:6: note: candidate function [with T = std::__1::enable_if<true, int>]
void foo(typename T::type s) {
^
test.cpp:21:6: note: candidate function [with T = std::__1::enable_if<true, int>]
void foo(int s) {
^
1 error generated.
Sto utilizzando il codice simile a questo per un progetto su cui sto lavorando e ho paura che ci sia un modo sottile per il linguaggio che ho Non capisco che causerà qualche comportamento indefinito in alcuni casi. Dovrei anche menzionare che si compila sia su Clang che su VS11, quindi non penso che sia solo un bug del compilatore.
Edit: corretto secondo caso (errore di battitura); aggiunto un messaggio di errore da Clang.
Modifica n. 2: per quelli di voi che hanno chiesto cosa significa T :: type.
Da http://en.cppreference.com/w/cpp/types/enable_if:
modello < bool B, classe T = vuoto> struct enable_if;
Se B è vero, std :: enable_if ha un tipo typedef di membro pubblico, uguale a a T; altrimenti, non vi è alcun membro typedef.
enable_if è una struttura. Fondamentalmente, se l'espressione valutata nel primo parametro template di enable_if è vera (e nel caso dei miei esempi sopra, lo è), allora ci sarà un membro pubblico type
che ha lo stesso tipo del secondo parametro template.
Nel caso di enable_if<true, int>
, enable_if :: type ha un tipo di int.
Non sorprende che il tuo ultimo caso non venga compilato. Stai utilizzando due argomenti del modello quando la funzione (s) ne riceve uno solo. –
Grazie, credo di aver copiato il caso sbagliato lì. Fisso. – vmrob
Sono un noob in C++ quindi non disturbarmi ... Il primo esempio non funziona perché stai ignorando il primo metodo? Sono interessato a conoscere la risposta a questo. Ho intenzione di imparare il C++ l'anno prossimo. –