Jak zainicjować wektor C ++ 17 par z opcjonalnym elementem

34

Jak w C ++ 17 zadeklarować i zainicjować wektor par (lub krotek) za pomocą opcjonalnego elementu?

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

Mam parę, w której drugi element może być zerowy / opcjonalny.

Eugene
źródło
1
std::piecewise_constructmoże również zapewnić ciekawe alternatywy.
Marc Glisse
4
Czy to odpowiada na twoje pytanie? Jak przypisać „nic” do std :: opcjonalne <T>?
Julien Lopez
@JulienLopez To mówi o przydziale.
LF
@LF To samo pytanie usuwa się nieistotny kontekst: jak utworzyć pustą opcjonalną?
Julien Lopez
1
@JulienLopez W C ++ inicjalizacja i przypisanie są bardzo różne. To, że oba pytania mają nakładające się rozwiązania, nie oznacza, że ​​są one takie same. W szczególności pamiętaj, że nie chcesz resettutaj korzystać .
LF

Odpowiedzi:

49

Szukasz std::nulloptzamiast nullptr.

std::vector<std::pair<int, std::optional<bool> > > vec1 =
  { {1, true}, {2,false}, {3,std::nullopt} };
maska ​​bitowa
źródło
3
(Pochodzi z linku z gorącymi pytaniami w sieci) Czy kod C ++ zawsze std::tak spamuje ? Dlaczego nie tylko using std::vectori przyjaciele, więc możesz po prostu pisać vector<pair<int, optional<bool>>? Czyta o wiele zdrowiej
Alexander - Przywróć Monikę
17
@ Alexander-ReinstateMonica „Czyta o wiele bardziej zdrowo” jest subiektywny. Druga strona argumentu czytelność jest coś takiego: nie chcę mieć, aby przejść całą drogę z powrotem do początku pliku, aby dowiedzieć się , które szczególnie vector , pair, optionalitp używam w tej linii. Dołączenie wbudowanej przestrzeni nazw mówi mi jednoznacznie, skąd ta funkcja pochodzi i co robi; linia jest samodzielna. Jest to szczególnie prawdziwe w przypadku większych projektów (ponieważ całkowicie eliminuje konflikty przestrzeni nazw), ale jest również przydatne w przypadku zwięzłych przykładów kodu.
prawdopodobnie_jeden
3
@ Alexander-ReinstateMonica Ta logika jest w porządku, jeśli masz pełny nadzór i kontrolę nad dowolnym kodem, który używa właśnie napisanego kodu (ponieważ wtedy dokładnie wiesz, kiedy zdarza się „przypadek, w którym dochodzi do kolizji”). Ale jeśli robisz coś takiego, jak na przykład tworzenie biblioteki lub interfejsu API, który jest przeznaczony do użytku przez grupę innych programistów, nie możesz nadzorować każdego użycia, aby dowiedzieć się, czy / kiedy nastąpi taka kolizja. Zwykle lepiej w tym (stosunkowo częstym) przypadku jest zapobieganie kolizjom, niż naprawianie ich dopiero wtedy, gdy ktoś narzeka, że ​​produkt jest uszkodzony.
prawdopodobnie_jeden
3
@ Alexander-ReinstateMonica Z którego z poniższych elementów natychmiast zdajesz sobie sprawę, że jest to nazwa najwyższego poziomu std? arg, count, find,size
LF
4
@ Alexander-ReinstateMonica jest dla mnie std::całkowicie dyskretny. Byłoby inaczej, gdyby nazwa przestrzeni nazw była znacznie dłuższa.
Carsten S
24

Lub prosta domyślna konstrukcja:

std::vector<std::pair<int, std::optional<bool>>> vec1 {
    {1, true}, {2,false}, {3,{}}
};
Marek R.
źródło
6
Podczas gdy to działa, std::nulloptlepiej komunikuje zamiary.
Williham Totland