Wie verhindere ich, dass boost :: optionalT mit 0 fehlerhaft erstellt wird?

8

boost::optional<T> (1.51) bietet eine Möglichkeit, Objekte zu konstruieren, die für meine Benutzer sehr gefährlich sind und die ich gerne verhindern möchte. Nehmen wir an, ich habe meine eigene Integer-Klasse und möchte eine optionale Integer-Klasse übergeben und in einer Klasse speichern:

%Vor%

und jetzt, hier ist, wie Benutzer die Klasse verwenden würden:

%Vor%

Ich würde gerne verstehen, was hier vor sich geht und dieses Verhalten verhindern.

Interessanterweise

%Vor%

boost::none ist absolut ein gültiger Wert für mein Feld, aber ein boost::none sneak-up zu haben, wenn der Benutzer versucht, 0 einzutippen, ist schrecklich irreführend und gefährlich.

Die Absicht könnte ein bisschen versteckt sein, da ich nicht wirklich eine myint -Klasse auslege und ich nicht wirklich eine class myclass habe, die wenig bis gar keinen Zweck erfüllt. Anyways Ich muss 10 oder so optionale Ints zu einer Funktion senden und Deduplizierung würde nicht funktionieren. (Sie können sich vorstellen, dass ich Sie nach Ihrem Alter gefragt habe, nach Ihrer Größe und Ihrem Wohlstand und dass es drei spezielle Knöpfe gibt, mit denen Sie überprüfen können, ob Sie eine Frage nicht beantworten möchten)

Ich habe eine Antwort gepostet, die unten zu funktionieren scheint (gebaut von Mooings Duck & amp; Ilonesmiz Vorschlag, aber leichter). Ich bin jedoch froh, Kommentare darüber zu hören.

    
Gurg Hackpof 06.03.2013, 18:00
quelle

4 Antworten

1

Dieser Code (Inspiriert von Ilonesmiz) scheint die Arbeit gut zu machen und ist ein bisschen leichter als der Ansatz von Mooing Duck, verwendet aber immer noch den magischen Vorlagentrick.

%Vor%

Hier ist der Beweis .
Wenn C ++ das 0 sieht, denkt es "hmm, das ist wahrscheinlich ein int, aber es könnte ein Zeiger auf etwas sein!" (nur für 0 , keine anderen Zahlen) Aber wenn Sie das 0 an eine Funktion übergeben, muss es sich für einen Typ entscheiden und wählt daher den Standardwert int . Während im Original ein 0 an eine Funktion übergeben wurde, die ein myint oder einen Zeiger erwartet ( boost::none_t ist ein Zeiger). 0 ist kein myint, aber es kann ein Zeiger sein, also hat er diesen ausgewählt.

    
Gurg Hackpof 07.03.2013, 13:50
quelle
3

Lassen Sie nicht zu, dass der Konstruktor ein boost::optional nimmt. Ich würde stattdessen so etwas tun.

%Vor%

Aber wenn ich darüber nachdenke, ist mir nicht ganz klar, was Sie erreichen wollen und was Sie vermeiden wollen. Was ist der Zweck des Mitglieds optional ?

    
AxelOmega 06.03.2013 18:09
quelle
3

Das ist hässlicher als ich mag, aber es scheint Ihre Bedenken zu adressieren. Es funktioniert, indem das übergebene Argument an myclass perfekt an ein Paar von Funktionen weitergeleitet wird, die entweder einen int oder einen boost::none_t annehmen, wobei der implizite benutzerdefinierte Konstruktor umgangen wird. Dies funktioniert, weil 0 mit int besser als boost::none_t übereinstimmt und ein impliziter benutzerdefinierter Konstruktor die schlechteste Übereinstimmung ist.

%Vor%

Proof of Concept . Moderne Compiler sollten schlau genug sein, um die Kopie zu kopieren, aber das sollte für ein int keine Rolle spielen.

    
Mooing Duck 06.03.2013 18:54
quelle
1

Ich denke, das Problem ist nur für optionale int sinnvoll. Eine Lösung könnte darin bestehen, zwei Konstruktoren bereitzustellen:

%Vor%

Es stimmt, dass Sie ein wenig den Vorteil von boost::optional ... verlieren

    
FredericS 06.03.2013 18:24
quelle

Tags und Links