So initialisieren Sie den C ++ 17-Vektor von Paaren mit einem optionalen Element

34

Wie deklarieren und initialisieren Sie in C ++ 17 einen Vektor von Paaren (oder Tupeln) mit einem optionalen Element?

    std::vector<std::pair<int, optional<bool> > > vec1 = { {1, true},
                                                           {2, false}, 
                                                           {3, nullptr}};

Ich habe ein Paar, bei dem das zweite Element null / optional sein kann.

Eugene
quelle
1
std::piecewise_constructkann auch interessante Alternativen bieten.
Marc Glisse
4
Beantwortet das deine Frage? Wie ordne ich std :: optional <T> "nichts" zu?
Julien Lopez
@ JulienLopez Das spricht von Zuordnung.
LF
@LF Es ist dieselbe Frage, wenn Sie den irrelevanten Kontext entfernen: Wie erstellen Sie eine leere Option?
Julien Lopez
1
@ JulienLopez In C ++ sind Initialisierung und Zuweisung im Allgemeinen sehr unterschiedlich. Nur weil die beiden Fragen zufällig überlappende Lösungen haben, heißt das nicht, dass sie gleich sind. Beachten Sie insbesondere, dass Sie hier nicht verwenden möchten reset.
LF

Antworten:

49

Sie suchen std::nulloptstatt nullptr.

std::vector<std::pair<int, std::optional<bool> > > vec1 =
  { {1, true}, {2,false}, {3,std::nullopt} };
Bitmaske
quelle
3
(Kommt hier vom Link zu Fragen zum heißen Netzwerk) Spammt C ++ - Code immer std::so? Warum nicht einfach using std::vectorund Freunde, damit du einfach schreiben kannst vector<pair<int, optional<bool>>? Liest viel vernünftiger
Alexander - Reinstate Monica
17
@ Alexander-ReinstateMonica "Liest viel vernünftiger" ist subjektiv. Die Kehrseite der Lesbarkeit Argument ist so etwas wie dieses: Ich möchte nicht den ganzen Weg zurück an die Spitze der Datei Figur gehen haben , aus denen bestimmte vector , pair, optionalusw. Ich bin in dieser Zeile mit. Das Einfügen des Namespace inline sagt mir eindeutig, woher diese Funktion kommt und was sie tut. Die Leitung ist in sich geschlossen. Dies gilt insbesondere für größere Projekte (da Namespace-Konflikte vollständig vermieden werden), aber auch für kurze Codebeispiele.
wahrscheinlich
3
@ Alexander-ReinstateMonica Diese Logik ist in Ordnung, wenn Sie die vollständige Überwachung und Kontrolle über jeden Code haben, der den gerade geschriebenen Code verwendet (denn dann wissen Sie genau, wann ein "Off-Fall, in dem Kollisionen auftreten" auftritt). Wenn Sie beispielsweise eine Bibliothek oder eine API entwickeln, die von einer Reihe anderer Entwickler verwendet werden soll, können Sie nicht jede einzelne Verwendung überwachen, um herauszufinden, ob / wann eine solche Kollision auftritt. In diesem (relativ häufigen) Fall ist es normalerweise besser, Kollisionen vorzubeugen, als sie erst zu beheben, nachdem sich jemand beschwert, dass Ihr Produkt defekt ist.
wahrscheinlich
3
@ Alexander-ReinstateMonica Aus welchem ​​der folgenden Namen ist Ihnen sofort ein Top-Level-Name ersichtlich std? arg, count, find,size
LF
4
@ Alexander-ReinstateMonica ist für mich std::völlig unauffällig. Es wäre anders, wenn der Name des Namespace viel länger wäre.
Carsten S
24

Oder verwenden Sie einfach die Standardkonstruktion:

std::vector<std::pair<int, std::optional<bool>>> vec1 {
    {1, true}, {2,false}, {3,{}}
};
Marek R.
quelle
6
Während dies funktioniert, std::nulloptkommuniziert Absicht besser.
Williham Totland