Was ist der Stand der Technik über Funktionen, um zu überprüfen, ob ein Wert gesetzt ist oder nicht ?
Beispielsweise analysiert der folgende Iterator Zellen. Einige Zellen enthalten einen Wert, andere Zellen sind leer.
Was ist der bequemste Weg?
%Vor%Reflexionen:
isset()
= & gt; umbenannt in isSet()
empty()
bezieht sich mehr auf die Sammlung von Containern, nicht nur auf eine einzelne Zelle: (operator void*
scheint der logische Weg zu sein, aber ist in C ++ 11-Streams veraltet
explicit operator
ist noch nicht unterstützt (mein Code muss mit alten Compilern kompatibel sein) Ich lese:
Ich bin beeindruckt, dass explicit_cast<T>
von Imperfect C ++: Practical Solutions [ ...] wurde nicht erwähnt. Das Konzept ist sehr einfach: Sie richten ein Pseudo-Schlüsselwort ein, das tatsächlich eine Vorlagenklasse ist, die die gewünschte Konvertierung implementiert. Ich habe dies in meiner eigenen C ++ Backports-Bibliothek ohne ein wichtiges Problem verwendet.
Sie verwenden das Pseudo-Schlüsselwort genau so, wie Sie es erwarten würden:
%Vor% Der beste Teil von allem, diese Lösung kann perfekt auf native explicit operator
in C ++ 11 abgebildet werden, was im Wesentlichen zu Null Overhead und nativer Syntax führt. Als Ergebnis ist es auch generischer als zu versuchen herauszufinden, ob "isset", "is_set", "is_Set", "isSet", etc ...
void*
hat Probleme, da es sich um eine gültige Konvertierungssequenz handelt, die in einigen Fällen nicht vorgesehen war. Viele Leute benutzen in C ++ 03 manchmal " safe bool idiom " wo Sie einen lokalen Mitgliedsfunktions-Zeigertyp haben Das enthält private Typen, so dass niemand eine Instanz davon außerhalb Ihrer Klasse haben könnte. Sie können das jedoch zurückgeben und zumindest nach True / False suchen.
Wenn Sie C ++ 11 verwenden, dann ist explicit operator bool
der Weg zu gehen, da es hauptsächlich für genau diese Fälle erfunden wurde.
In den meisten Fällen sollte man keine implizite Konvertierung verwenden, d. h. Ausdrücke wie operator bool()
in Ihrem Code verwenden.
Wenn Sie Instanzen Ihrer Klasse in einer if
-Anweisung verwenden wollen, erstellen Sie oft eine implizite Konvertierung, aber eine Signatur eines Member-Function-Prototyps, die Sie entweder auf einen Nicht-Op-Private verweisen Funktion oder NULL abhängig vom Status.
Sie werden auch oft bool operator!() const
für Ihre Klasse überladen. Da dies die gleiche Logik wie die implizite Konvertierung verwenden wird, implementieren Sie oft eine in Bezug auf die andere.
Etwas wie:
%Vor%Niemand kann jemals die Funktion aufrufen, die Sie vom Zeiger zurückgeben, weil sie einen MyPrivateType benötigt, und sie können keinen abrufen, weil sie privat ist.
Danke an alle Ihre Kommentare / Antworten / Beiträge. Hier habe ich die verschiedenen Ideen und andere Ideen, die im Netz gefunden wurden, zusammengeführt (ich habe viel Dokumentation und Quellcode gelesen).
bool isSet()
wie von @ j_random_hacker angegeben
Der logischste Weg. Beide Quellcodes (Bibliothek und Anwendung) sind für Anfänger verständlich. Und das passt zum KISS-Prinzip . Außerdem ist dies in andere Programmiersprachen wie Java portierbar ...
%Vor% Wenn die Funktion get()
isSet()
nicht überprüft und ein Entwickler (einer Anwendung) vergisst, isSet()
(vor get()
) aufzurufen, kann der Anwendungscode abstürzen (Segmentierungsfehler).
Wenn get()
function dagegen isSet()
aufruft, wird isSet()
zweimal ausgeführt. Trotzdem sollten neuere Compiler solche zweite unnötige isSet()
Verarbeitung vermeiden.
Einige Leute denken, dass die Ausnahme für die Binärcodeoptimierung schlecht ist. Wenn jedoch throw exception
inline ist, können die besten Compiler den Binärcode optimieren und besser als das
Außerdem kann diese Lösung den besten optimierten Binärcode ermöglichen, weil isSet()
zweimal aufgerufen wird. Dies hängt jedoch von den Kapazitäten der Compileroptimierung ab.
Bibliothek:
%Vor%Anwendung:
%Vor%operator explicit_cast<bool> () const
Bitte lesen Sie die gut geschriebene Antwort von Luis .
operator
schreiben Sie elegant if(it)
Diese Lösung kann mit expliziten Konvertierungsoperatoren, die in C ++ 11 eingeführt wurden , gut implementiert werden.
Bibliothek:
%Vor%Anwendung:
%Vor%Wir befinden uns jedoch immer noch im Jahr 2012, und der aktuelle Quellcode muss Compiler ohne Unterstützung von expliziten Konvertierungsoperatoren entsprechen. Auf diesen Compilern wurden Jahr für Jahr verschiedene Möglichkeiten implementiert. Ich präsentiere all diese im nächsten Kapitel.
if(it)
vor C ++ 11 Der Quellcode dieses Kapitels ist inspiriert von dem Buch Weitere C ++ - Idiome , geschrieben von Bjarne Stroustrup im Jahr 2004, genauer gesagt die Sektion The Safe Bool Idiom wie von PlasmaHH aufgezeigt.
operator bool
Wenn explicit
nicht verfügbar ist, könnten wir einfach den impliziten Konvertierungsoperator verwenden.
Bibliothek:
%Vor%Anwendung:
%Vor% Dies ist die Lösung, die in operator!
verwendet wird (v1.51 ) als Workaround von boost::thread
für explicit operator bool()
, unique_lock
, shared_lock
und upgrade_lock
.
Bibliothek:
%Vor%Anwendung:
%Vor% Dies ist die Lösung, die von STL-Streams verwendet wird. Siehe zum Beispiel die Datei bits / basic_ios.h ( upgrade_to_unique_lock
).
Bibliothek:
%Vor%Anwendung:
%Vor%operator void*
Diese Lösung wurde 1996 von Don Box vorgeschlagen.
Bibliothek:
%Vor%Anwendung:
%Vor%std::basic_ios
idiom wie von @ CashCow dargestellt
Bjarne Stroustrup hat das fertige Lösung ohne Nachteile. Unten ist eine vereinfachte Version.
Bibliothek:
%Vor%Anwendung:
%Vor%class
idiom Dies ist viel komplexer, bitte lesen Sie Wikibooks nach dem Quellcode.
>Bibliothek:
%Vor%Aktuelle STL und Boost bieten Einrichtungen. Einige Beispiele:
bool
:
Aber Matthew Wilson sagt in seinem Buch Imperfect C ++ , dass bool
zu größeren Abstrichen bei den Compilern führen kann Implementieren von Leere Basisoptimierung nicht. Obwohl es die meisten modernen Compiler tun, wenn es um einzelne Vererbung geht, kann es eine Größenstrafe mit Mehrfachvererbung geben.
Tags und Links c++ c++11 c++03 operator-keyword explicit-conversion