2015-08-26 16 views
5

Recentemente ho incontrato una versione interessante di enable_if utilizzo per consentire condizionalmente una funzione con leggermente migliore leggibilità perché il tipo di ritorno della funzione non fa parte del enable_if (vedi cleaner_usage):enable_if per funzioni con nessun tipo di ritorno tirato in esso

#include <type_traits> 

using maybe_integral = int /* = or float -- then won't compile */; 
using return_type = int; 

typename std::enable_if<std::is_integral<maybe_integral>::value, return_type>::type 
traditional_usage() 
{ 
    return 1; 
} 

template<typename std::enable_if<std::is_integral<maybe_integral>::value, int>::type = 0> 
return_type cleaner_usage() 
{ 
    return 2; 
} 

int main() 
{ 
    return traditional_usage() + cleaner_usage(); 
} 

In caso di errore, il meccanismo è chiaro (nessun membro type).

Ma come funziona esattamente negli altri casi? Perché assomiglia al campo inttypedef sostituito nel parametro tipo di modello con assegnazione imprevista.

+0

In realtà, è necessario fornire un esempio ben formato. – Barry

+0

@Barry, okay - dov'è un problema con quello attuale (cosa è necessario correggere)? –

+0

@Barry [qui] (http://coliru.stacked-crooked.com/a/05bdc97ab63fc99b). – Shoe

risposta

5

nel successo a caso:

template<typename std::enable_if<std::is_integral<float>::value, int>::type = 0> 
return_type cleaner_usage() 
{ 
    return 2; 
} 

sarebbe diventato equivalente a:

template<int = 0> 
return_type cleaner_usage() 
{ 
    return 2; 
} 

che è perfettamente legale, dato che alcuni tipi di valore sono autorizzati a comparire in un contesto parametro di modello. Credo che queste siano formalmente chiamato non di tipo parametri di modello, come descritto da §14.1/4:

Un non-modello di tipo-parametro assume uno dei seguenti tipi (opzionalmente cv qualificato):

  • tipo integrale o enumerazione,
  • puntatore di opporsi o puntatore a funzione,
  • riferimento Ivalue di opporsi o Ivalue riferimento alla funzione,
  • poi nter to member,
  • std::nullptr_t.