Ich finde oft, dass ich Konvertierungen (und allgemein die Usual arithmetic conversions) für bestimmte Konstruktoren oder Funktionen verhindern möchte. Ich neige dazu, schreiben:Verwendung von (Templated) gelöschte Funktionsüberladung, um übliche arithmetische Umwandlungen zu vermeiden
#include <iostream>
void foo(double f){
std::cout << "foo double" << f <<std::endl;
}
void foo(float) = delete;
// or template<typename T> void foo(T&& f) = delete;
void bar(unsigned int f){
std::cout << "bar uint " << f <<std::endl;
}
void bar(signed int) = delete;
// or template<typename T> void bar(T&& f) = delete;
Dies macht den Job ...
int main() {
auto i=2;
auto d=2.0;
auto f=2.0f;
foo(i); // prevented
foo(d); // OK
foo(f); // prevented
auto uil = 3ull;
auto ul = 3ul;
auto u = 3u;
bar(i); // prevented
bar(d); // prevented
bar(f); // prevented
bar(uil); // prevented
bar(ul); // prevented
bar(u); // OK
}
Nun ist es nur eine Frage des Geschmacks in diesen Fällen, wenn ich eine gelöschte Vorlage oder eine gelöschte Nicht-Vorlage verwenden Funktion, oder gibt es Fälle, in denen es darauf ankommt? Ich finde die gelöschte Vorlage expliziter, indem sie verhindert alle T, aber auf der anderen Seite, wenn dieses Muster mit Konstruktoren verwenden; Weiterleitungskonstruktoren have their issues. Im Fall der Vorlagenversion, wäre es besser, die gelöschte Vorlage stattdessen const T&
zu machen?
oder einfach 'T' (' Vorlage void foo (T) = löschen; '). –
Jarod42
@ Jarod42. Richtig ... –
Ein obskurer Fall, in dem sich die Dinge anders verhalten, ist etwas wie 'foo ({f});', was durch die Template-Version nicht verhindert wird, weil die Initialisierungsliste den Parameter zu einem nicht-abgeleiteten Kontext macht, so dass der Abzug fehlschlägt für die Vorlage, wobei nur die Nicht-Vorlage-Überladung verbleibt. (Ich kann den Link in der Frage nicht öffnen, ich weiß nicht, ob das dort erwähnt wurde.) – bogdan