Kurzfassung: Ich habe eine Template-Funktion, die "universal" ist, aber ich möchte den Benutzer zwingen, den Typ des Arguments explizit anzugeben, sie übergeben als Parameter an diese Funktion.Gibt es eine Möglichkeit, den Benutzer zu zwingen, den Template-Argumenttyp explizit anzugeben?
Irgendwelche Ideen?
Lange Version: klingt wie ein schreckliches Design, aber hier ist mein Fall und ich kann mir im Moment nichts besseres vorstellen.
Ich versuche ::setsockopt
in einer kleinen socket
Klasse "zu implementieren" (und ich möchte nicht Tonnen von Funktionen, verschiedene Argumente und das gleiche tun). Zum Beispiel:
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));
}
ABER, könnte dies auf die folgende Situation führen - set_option
mit 1
Aufruf versucht unsigned char
Option setzen würde zum Ausfall führen, wie 1
int
ist. Korrekte Verwendung wäre:
set_option< unsigned char >(level, option, 1);
als
set_option(level, option, 1);
kompiliert völlig in Ordnung, aber schrecklich falsch sein.
Andere Optionen aus der Standard-Bibliothek wäre 'typename add_const :: type &' oder 'typename add_lvalue_reference :: type', die wahrscheinlich ein bisschen klarer sind. Die Verwendung von 'enable_if' könnte die Leute dazu bringen zu glauben, dass einige SFINAE beteiligt sind. –
@ JonathanWakely Das ist ein guter Punkt. Auf der anderen Seite macht die Verwendung von 'add_const' oder' add_lvalue_reference' nicht klar, dass etwas Spezielles vor sich geht, und könnte jemanden dazu bringen, eine Code-Bereinigung durchzuführen, indem er einfach 'const OPTION_VALUE_TYPE &' ausdrückt. Ich denke, dass es für beide etwas zu sagen gibt, und ich denke, der klarste Ansatz besteht darin, diese "Identitäts" -Hilfsklasse zu erstellen und einfach die Standard-Bibliothekstypen zu vergessen. – hvd
Ja, guter Punkt. "Identität" dient keinem anderen Zweck als dem, also ist es die expressivste Lösung. –