Sto riscontrando un problema relativo all’uso appropriato di enable_if e della specializzazione del modello.
Dopo aver modificato l’esempio (per motivi di riservatezza), ecco un esempio comparabile:
Ho una funzione chiamata “less” che controlla se 1st arg è inferiore a 2nd arg. Diciamo che voglio avere 2 diversi tipi di implementazioni a seconda del tipo di input: 1 implementazione per intero e un’altra per doppio.
Il codice che ho finora assomiglia a questo –
#include #include template <class T, class = typename std::enable_if<std::is_floating_point::value>::type> bool less(T a, T b) { // .... } template <class T, class = typename std::enable_if<std::is_integral::value>::type> bool less(T a, T b) { // .... } int main() { float a; float b; less(a,b); return 0; }
Il codice sopra non viene compilato perché – Dice che sto ridefinendo il metodo meno.
Gli errori sono:
Z.cpp:15:19: error: template parameter redefines default argument class = typename std::enable_if<std::is_integral::value>::type> ^ Z.cpp:9:19: note: previous default template argument defined here class = typename std::enable_if<std::is_floating_point::value>::type> ^ Z.cpp:16:11: error: redefinition of 'less' bool less(T a, T b) { ^ Z.cpp:10:11: note: previous definition is here bool less(T a, T b) { ^ Z.cpp:23:5: error: no matching function for call to 'less' less(a,b); ^~~~ Z.cpp:15:43: note: candidate template ignored: disabled by 'enable_if' [with T = float] class = typename std::enable_if<std::is_integral::value>::type> ^ 3 errors generated.
Qualcuno può indicare qual è l’errore qui?
Gli argomenti del modello predefinito non fanno parte della firma di un modello di funzione. Quindi nel tuo esempio hai due sovraccarichi identici di less
, il che è illegale. clang si lamenta della ridefinizione dell’argomento di default (che è anche illegale secondo §14.1 / 12 [temp.param]), mentre gcc produce il seguente messaggio di errore:
errore: ridefinizione di ‘
template
‘bool less(T, T)
Per correggere l’errore, spostare l’espressione enable_if
dall’argomento predefinito su un parametro modello fittizio
template ::value, int>::type* = nullptr> bool less(T a, T b) { // .... } template ::value, int>::type* = nullptr> bool less(T a, T b) { // .... }
Un’altra opzione è usare enable_if
nel tipo restituito, sebbene ritenga che sia più difficile da leggere.
template typename std::enable_if::value, bool>::type less(T a, T b) { // .... } template typename std::enable_if::value, bool>::type less(T a, T b) { // .... }