0Pricing
C++ Academy · Lekcja

std::visit

Przetwarzaj alternatywy wariantu

std::visit to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C++ Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C++ Academy zawiera 4 lekcji w sumie.

Dlaczego std::visit

Ręczne sprawdzanie każdej alternatywy za pomocą get_if szybko staje się rozwlekłe. std::visit stosuje wywoływalny obiekt do typu aktualnie przechowywanego przez wariant i samodzielnie obsługuje wybór właściwej operacji.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 4;
    std::visit([](auto x){ std::cout << x << "\n"; }, v);
}

Visitor z ogólną lambdą

Lambda przyjmująca auto działa dla każdej alternatywy, jeśli jej ciało kompiluje się dla wszystkich tych typów. W tym przykładzie wypisujemy dowolny aktywny typ.

#include <iostream>
#include <string>
#include <variant>
int main() {
    std::variant<int, std::string> v = std::string("hi");
    std::visit([](const auto& x){ std::cout << x << "\n"; }, v);
}

Zwracanie wartości

std::visit może zwracać wartość. Każda gałąź musi zwracać ten sam typ.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 2.5;
    double d = std::visit([](auto x){ return x * 2.0; }, v);
    std::cout << d << "\n";
}

Zachowanie zależne od typu za pomocą if constexpr

Aby w jednej ogólnej lambdzie wykonywać różne działania zależnie od typu, należy połączyć if constexpr z std::decay_t i std::is_same_v.

#include <iostream>
#include <string>
#include <variant>
#include <type_traits>
int main() {
    std::variant<int, std::string> v = 5;
    std::visit([](const auto& x){
        using T = std::decay_t<decltype(x)>;
        if constexpr (std::is_same_v<T, int>) std::cout << "int " << x << "\n";
        else std::cout << "str " << x << "\n";
    }, v);
}

Visitor będący strukturą

Można również napisać strukturę z wieloma przeciążeniami operator(), po jednym dla każdego typu. Kompilator wybierze pasujące przeciążenie.

#include <iostream>
#include <string>
#include <variant>
struct Printer {
    void operator()(int i) const { std::cout << "int " << i << "\n"; }
    void operator()(const std::string& s) const { std::cout << "str " << s << "\n"; }
};
int main() {
    std::variant<int, std::string> v = std::string("yo");
    std::visit(Printer{}, v);
}

Idiom overloaded

Popularny pomocnik łączy kilka lambd w jeden obiekt visitor. Każda lambda obsługuje konkretny typ.

#include <iostream>
#include <string>
#include <variant>
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
int main() {
    std::variant<int, std::string> v = 8;
    std::visit(overloaded{
        [](int i){ std::cout << "i=" << i << "\n"; },
        [](const std::string& s){ std::cout << "s=" << s << "\n"; }
    }, v);
}

Kompletność obsługi

Visitor musi obsługiwać każdą alternatywę, w przeciwnym razie kod się nie skompiluje. To sprawdzenie na etapie kompilacji zapobiega pominięciu któregoś przypadku.

Odwiedzanie i modyfikowanie

Jeśli przekażesz wariant przez referencję nieconst, visitor będzie mógł modyfikować przechowywaną wartość w miejscu.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> v = 10;
    std::visit([](auto& x){ x += 1; }, v);
    std::cout << std::get<int>(v) << "\n";
}

Wiele wariantów

std::visit może jednocześnie przyjmować kilka wariantów; visitor otrzymuje wtedy po jednym argumencie dla każdego wariantu.

#include <iostream>
#include <variant>
int main() {
    std::variant<int, double> a = 2;
    std::variant<int, double> b = 3.0;
    auto sum = std::visit([](auto x, auto y){ return x + y; }, a, b);
    std::cout << sum << "\n";
}

Wybór stylu visitora

Ogólnej lambdy z auto należy używać do jednolitej obsługi, idiomu overloaded do przejrzystej logiki zależnej od typu, a visitora będącego strukturą wtedy, gdy zachowanie ma być używane ponownie w wielu miejscach wywołania.

Visit a get_if

get_if dobrze sprawdza się przy pojedynczym szybkim sprawdzeniu, ale std::visit lepiej skaluje się w większym kodzie: wymusza kompletną obsługę alternatyw i skupia całą logikę zależną od typu w jednym miejscu.

Szybkie sprawdzenie

Sprawdź swoją wiedzę na temat std::visit.

Podsumowanie

Poznałeś/Poznałaś std::visit:

  • Przekazuje wywoływalny obiekt do aktywnej alternatywy.
  • Można używać ogólnych lambd, if constexpr, visitorów będących strukturami lub idiomu overloaded.
  • Visitery muszą obsługiwać wszystkie alternatywy (jest to sprawdzane podczas kompilacji).
  • Mogą zwracać wartości i jednocześnie odwiedzać wiele wariantów.

Często zadawane pytania

Czy lekcja „std::visit” jest bezpłatna?

Tak — pełny tekst „std::visit” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C++ Academy, przejdź na CoddyKit PRO. Kurs C++ Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „std::visit”?

Przetwarzaj alternatywy wariantu Ćwiczysz C++ Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C++ Academy?

Nie wymagamy żadnego doświadczenia. C++ Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „std::visit”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C++ Academy?

Tak. Każda lekcja C++ Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Zakresowa enum class
  2. Unie i związane z nimi ryzyko
  3. std::variant
  4. std::visit
← Powrót do C++ Academy