isSet () oder operator void * () oder explizite opertor bool () oder etwas anderes?

8

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:

  1. mein Chef versteht nicht isset() = & gt; umbenannt in isSet()
  2. empty() bezieht sich mehr auf die Sammlung von Containern, nicht nur auf eine einzelne Zelle: (
  3. operator void* scheint der logische Weg zu sein, aber ist in C ++ 11-Streams veraltet
  4. explicit operator ist noch nicht unterstützt (mein Code muss mit alten Compilern kompatibel sein)

Ich lese:

olibre 23.05.2017, 12:32
quelle

4 Antworten

1

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.

%Vor%

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 ...

aufgerufen werden sollen     
Luis Machuca 20.11.2013, 15:49
quelle
6

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.

    
PlasmaHH 02.11.2012 10:53
quelle
1

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.

    
CashCow 02.11.2012 11:10
quelle
0

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).

Überprüfen Sie den Wert Präsenz

1. 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.

2. Gibt einen Flag-Wert oder einen Standardwert zurück, wie von einer meiner Kollegen vorgeschlagen

%Vor%

3. Wurfausnahme wie von Matthäus M aufgezeigt

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%

4. Verwenden von operator explicit_cast<bool> () const

Bitte lesen Sie die gut geschriebene Antwort von Luis .

5. Mit 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.

Aktivieren Sie die Anweisung 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.

1. implizit operator bool

Wenn explicit nicht verfügbar ist, könnten wir einfach den impliziten Konvertierungsoperator verwenden.

Bibliothek:

%Vor%

Anwendung:

%Vor%

2. %Code%

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%

3. %Code%

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%

4. implizite Konvertierung in eine undefinierte verschachtelte operator void*

Diese Lösung wurde 1996 von Don Box vorgeschlagen.

Bibliothek:

%Vor%

Anwendung:

%Vor%

5. Safe 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%

6.Wiederverwendbarer Safe class idiom

Dies ist viel komplexer, bitte lesen Sie Wikibooks nach dem Quellcode.

>

Bibliothek:

%Vor%

Aktuelle STL und Boost bieten Einrichtungen. Einige Beispiele:

  • GNU STL - & gt; Siehe Dateien tr1 / functional und exception_ptr.h
  • Jede Boost-Komponente verwendet ihr eigenes bool :
    • Geist - & gt; siehe Dateien spirit / include / classic_safe_bool.hpp und spirit / home / classic / core / safe_bool.hpp
    • IOstream - & gt; Siehe Datei iostreams / device / mapped_file.hpp
    • Parameter - & gt; Parameter / aux_ / may.hpp
    • Optional
    • Funktion
    • Reichweite
    • Logik (tribool)

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.

    
olibre 23.05.2017 11:54
quelle