Specializzazione del modello e problemi enable_if

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) { // .... }