So verwenden Sie boost :: optional
Ich versuche, mit boost::optional
als unten.
#include <iostream>
#include <string>
#include <boost/optional.hpp>
struct myClass
{
int myInt;
void setInt(int input) { myInt = input; }
int getInt(){return myInt; }
};
boost::optional<myClass> func(const std::string &str)
{
boost::optional<myClass> value;
if(str.length() > 5)
{
//If greater than 5 length string. Set value to 10
value.get().setInt(10);
}
else if (str.length() < 5)
{
//Else set it to 0
value.get().setInt(0);
}
else
{
//If it is 5 set the value to 5
value.get().setInt(5);
}
return value;
}
int main()
{
boost::optional<myClass> v1 = func("3124");
boost::optional<myClass> v2 = func("helloWorld");
boost::optional<myClass> v3 = func("hello");
if (v1)
std::cout << "v1 is valid" << std::endl;
else
std::cout << "v1 is not valid" << std::endl;
if (v2)
std::cout << "v2 is valid" << std::endl;
else
std::cout << "v3 is not valid" << std::endl;
if (v3)
std::cout << "v3 is valid" << std::endl;
else
std::cout << "v3 is not valid" << std::endl;
return 0;
}
Bekomme ich folgenden Fehler
prog.exe:
/usr/local/boost-1.55.0/include/boost/optional/optional.hpp:631:
boost::optional::reference_type boost::optional::get() [mit T =
myClass; boost::optional::reference_type = myClass&]: Assertion
`this->is_initialized()' ist fehlgeschlagen.
Vermutlich die optionale variable nicht richtig initialisiert. Wie zu tun es der richtige Weg?
EDIT:: hat einige sehr gute Antworten, nur ein paar mehr Fragen 1. Ist es eine gute Idee zu verwenden make_optional
am Ende 'func'
Funktion und zurückgeben? Auch 2. Ich dachte, die Zuordnung boost::none
ausdrücklich betonen, dass ich keinen Wert zuweisen und das ist, warum boost::none
. Aber nicht sicher, ob das gültig ist?
InformationsquelleAutor der Frage polapts | 2014-03-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Einen default-konstruiert
boost::optional
ist leer - es enthält keinen Wert, so kann man das auch nicht nennenget()
. Sie haben, initialisieren Sie es mit einem gültigen Wert:Alternativ können Sie eine in-place-Fabrik zu vermeiden, kopieren Sie die Initialisierung (aber die Kopie wird höchstwahrscheinlich erstellte sowieso), allerdings habe ich keine Erfahrung mit, also kann ich nicht ein Beispiel geben.
Als Seite beachten, können Sie
->
im Ortget()
wie diese:Aber das ist nur eine Frage der stilistischen Präferenz, beide sind gleichermaßen gültig.
InformationsquelleAutor der Antwort Angew
Zwei einfache Ansätze:
beachten Sie, dass die Rücksendung eine
optional
aus einer Funktion, die nie wieder ein leeres optional ist eine schlechte Idee.optional
verhält sich wie ein Zeiger auf lese-Zugriff-Sie können nur Lesen den Wert aus, wenn Sie bereits überprüft, dort ist etwas zu Lesen. Sie können überprüfen, ob es dort etwas zu Lesen tutbool something_to_read = opt;
.Können Sie, aber schreiben Sie auf, Wann immer. Wenn es nichts gibt, das es schafft etwas. Wenn es etwas gibt, wird es überschrieben.
.get()
ist ein Lesen, nicht schreiben, den Betrieb. (Sie "liest" die Referenz) Es ist nur sicher zu verwenden, wenn dieoptional
ist engagiert und hat die Daten. Verwirrend ist, können Sie schreiben, um die "lese-Zugriff".get()
return-Wert, da es eine non-const Referenz.Also vielleicht "Lesen" und "schreiben" sind böse Worte zu verwenden. 🙂
Ist es manchmal hilfreich, optional als Wert-und-Zeiger miteinander vermischt. Es ist ein möglicherweise null-Zeiger zu einer im Besitz Puffer Speicher, der möglicherweise oder möglicherweise nicht halten eine Kopie von dem Typ.
Wenn Sie den Mauszeiger innerhalb der optionalen null ist, dann wird der Puffer nicht initialisiert. Wenn es Punkte im Puffer, dann wird der Puffer initialisiert.
.get()
dereferenziert, die Zeiger und gibt das resultierende Verweis ohne überprüfen.=
prüft den Zeiger, wenn er null ist, bedeutet es einen copy-Konstrukt aus der rhs in den Puffer und setzt den Zeiger. Wenn nicht, es weist nur auf den Puffer.(Der Zeiger ist eine konzeptuelle: in der Regel umgesetzt als
bool
flag).Finde ich mit
*optional
besser zu sein alsoptional.get()
wie "Sie müssen überprüfen, bevor Sie dereferenzieren" ist mehr offensichtlich mit der dereference-operator.InformationsquelleAutor der Antwort Yakk - Adam Nevraumont
Als eine Randnotiz, dieser code muss nicht boost::optional, da es keine code-Zweig, der gibt ein leeres Objekt (es ist semantisch äquivalent zu der Rückkehr ein myClass-Instanz).
Leerem Rückgabewert optional, verwenden Sie diese:
Idiomatische client-code (nicht pre-initialisieren Ihre Werte):
InformationsquelleAutor der Antwort utnapistim
entsprechend zu steigern,optionale default-ctor erzeugen Sie eine optionale obj als ungültig
InformationsquelleAutor der Antwort camino