Versione breve: Ho una funzione template, che è "universale", ma voglio forzare l'utente a specificare esplicitamente il tipo dell'argomento, passano come parametro a questa funzione.Esiste un modo per forzare l'utente a specificare esplicitamente il tipo di argomento del modello?
Qualche idea?
Versione lunga: suona come un disegno terribile, ma qui è il mio caso e non riesco a pensare a qualcosa di meglio in questo momento.
Sto cercando di "implementare" ::setsockopt
in una piccola classe socket
(e non voglio avere tonnellate di funzioni, prendere argomenti diversi e fare lo stesso). Per esempio:
template< typename OPTION_VALUE_TYPE >
bool set_option(int level, int option_name, const OPTION_VALUE_TYPE& value)
{
return -1 != ::setsockopt(fd_, level, option_name, &value, sizeof(value));
}
MA, questo potrebbe portare alla seguente situazione - invocando set_option
con 1
, cercando di impostare unsigned char
opzione porterebbe al fallimento, come è 1
int
. uso corretto sarebbe:
set_option< unsigned char >(level, option, 1);
come
set_option(level, option, 1);
compilerà perfettamente bene, ma sarà terribilmente sbagliato.
Altre opzioni dalla libreria standard sarebbero utilizzare 'typename add_const :: type &' or 'typename add_lvalue_reference :: type', che sono probabilmente un po 'più chiari. Usare 'enable_if' potrebbe confondere le persone nel pensare che ci sia qualche SFINAE coinvolto. –
@JonathanWakely Questo è un buon punto. D'altro canto, l'uso di 'add_const' o' add_lvalue_reference' non rende chiaro che sta succedendo qualcosa di speciale, e potrebbe indurre qualcuno a fare una pulizia del codice pensando che potrebbe essere semplicemente semplificata con l'ortografia di 'const OPTION_VALUE_TYPE &'. Penso che ci sia qualcosa da dire per entrambi, e penso che l'approccio più chiaro sia quello di creare la classe helper 'identity', e semplicemente dimenticare i tipi di libreria standard. – hvd
Sì, buon punto. 'identity' non ha altro scopo se non quello di farlo, quindi è la soluzione più espressiva. –