Wie kann ich vermeiden, implizite Konvertierungen auf nicht-Bau-Funktionen?
Wie kann ich vermeiden, dass die implizite Typumwandlung, die auf nicht-Bau-Funktionen?
Ich habe eine Funktion, die einen integer als parameter
aber wird diese Funktion auch Zeichen, bools, und sehnt sich danach.
Ich glaube, es tut dies, indem er implizit Gießen Sie.
Wie kann ich dies vermeiden, so dass die Funktion akzeptiert nur Parameter des entsprechenden Typs, und wird sich weigern zu kompilieren sonst?
Es ist ein Schlüsselwort "explicit", aber es funktioniert nicht auf nicht-Bau-Funktionen. :\
was kann ich tun?
Folgende Programm kompiliert, obwohl ich es gern, nicht zu:
#include <cstdlib>
//the function signature requires an int
void function(int i);
int main(){
int i{5};
function(i); //<- this is acceptable
char c{'a'};
function(c); //<- I would NOT like this to compile
return EXIT_SUCCESS;
}
void function(int i){return;}
*bitte achten Sie auf jegliche missbräuchliche Verwendung der Terminologie und Annahmen
- by the way, die Fähigkeit zu übergeben, char, long, bool, oder im Grunde jedem anderen integer-Typ, wo ein int erwartet wird ist, weil der integer-promotion und conversion-Regeln in der Sprache. Dies ist ein anderer Mechanismus als die implizite Konvertierung geschieht mit nicht-explizite Konstruktoren.
- +1 für die Frage keine wirklich gute, Allgemeine Lösungen noch nicht!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nicht direkt, weil ein
char
wird automatisch gefördertint
.Können Sie zu einem trick greifen, aber: erstellen Sie eine Funktion, der eine
char
als parameter und nicht die Umsetzung. Es kompiliert wird, aber Sie erhalten einen linker-Fehler:Aufruf der Funktion mit einem
char
parameter brechen die build.Sehen http://ideone.com/2SRdM
Terminologie: nicht-construcing Funktionen? Meinst du eine Funktion, die nicht einen Konstruktor?
=delete
es und bekommen eine Kompilierungs-Fehler, nicht ein linker-Fehler.char
. Möglicherweise ist die Anzahl der unerwünschten eigentliche argument-Typen ist unbeschränkt. Also den Allgemeinen Fall nennen würde, für eine ziemlich große Anzahl von Funktions-Deklarationen. Die "offensichtliche" Lösung gibt es zu templatize. Aber dann, man entfernt die Möglichkeit, eine Allgemeine Vorlagen überlastung.char
zuint
.Funktion definieren Vorlage für alle anderen Typen:
Dies ist, weil die nicht-template-Funktionen mit direkten matching werden immer zuerst berücksichtigt. Dann ist die Funktion Vorlage mit direktem Spiel betrachtet werden - so noch nie
function<int>
verwendet werden. Aber für alles andere, wie char,function<char>
verwendet werden - und dies gibt Ihrer Zusammenstellung errrors:FEHLER:
Diese ist C++ - 03 Art:
hton
undntoh
Funktionen, die funktionieren nur mit dem richtigen Typ.Hier ist eine Allgemeine Lösung, die verursacht einen Fehler zur compile-Zeit, wenn
function
heißt mit nichts, aber ein intEs funktioniert, indem Sie beliebigen Typ für das argument der Funktion, sondern mit
is_int
als Typ-level-Prädikat. Die generische Implementierung vonis_int
hat einen falschen Wert, aber die explizite Spezialisierung für den Datentyp int hat den Wert true, so dass die statische assert garantiert, dass das argument hat genau Typint
ansonsten gibt es einen compile-Fehler.value
.Gut, ich werde diese Antwort mit dem code unten, aber selbst wenn es funktioniert mit Visual C++, im Sinne der Herstellung der gewünschten Zusammenstellung Fehler, MinGW-g++ 4.7.1 akzeptiert es, und ruft die rvalue-Referenz Konstruktor!
Ich denke, es muss zu einem compiler-Fehler, aber ich könnte falsch sein, so jemanden?
Ohnehin, hier ist der code, welcher kann sich um ein standard-konforme Lösung (oder es kann sich herausstellen, dass das ein thinko auf mein Teil!!!!):
template <class T> void function(T) = delete;
....Für C++14 (und ich glaube, dass C++11), können Sie deaktivieren Sie die copy-Konstruktoren durch überladen rvalue-Referenzen:
Beispiel:
Sagen, Sie haben eine Basis
Binding<C>
Klasse, woC
ist entweder die Basis -Constraint
Klasse oder einer vererbten Klasse. Sagen Sie speichernBinding<C>
durch einen Wert in einem Vektor, und übergeben Sie eine Referenz auf die Bindung und, die Sie wünschen, um sicherzustellen, dass Sie nicht bewirken, dass eine implizite Kopie.Können Sie dies durch löschen
func(Binding<C>&& x)
(pro PiotrNycz Beispiel) für rvalue-Referenz besonderen Fällen.Snippet:
Ausgabe:
Fehler (mit
clang-3.9
imbazel
, wenn die betreffende Zeile ist auskommentiert):Vollständige Code: prevent_implicit_conversion.cc
Vielleicht können Sie ein struct, um die zweite Funktion private:
Dieser Code wird nicht kompiliert:
Zuerst habe ich versucht PiotrNycz Ansatz (C++03, die ich bin gezwungen, für ein Projekt), dann versuchte ich zu finden ein allgemeinerer Ansatz, und kam mit dieser
ForcedType<T>
template-Klasse.Wenn ich mich nicht Irre, sind diese drei Spezialisierungen sollten Sie für alle Anwendungsfälle. Ich bin mir nicht sicher, ob eine Spezialisierung für rvalue-Referenz (C++11 aufwärts) tatsächlich benötigt wird oder der von-Wert genügt.
Würde man es verwenden, wie dies im Fall einer Funktion mit 3 Parametern, deren 3. parameter nicht zulässt, dass implizite Konvertierungen: