C++ Academy · Lekcja

std::function

Przechowuj dowolne obiekty wywoływalne

Lekcja 2 z 413 kroki

std::function to bezpłatna lekcja C++ Academy na CoddyKit. To lekcja 2 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.

Czym jest std::function?

std::function to opakowanie z wymazywaniem typu, które może przechowywać dowolny obiekt wywoływalny zgodny z określoną sygnaturą: zwykłą funkcję, lambdę, funktor lub wyrażenie utworzone za pomocą wiązania.

  • Jest deklarowany za pomocą docelowej sygnatury.
  • Jest dostępny w nagłówku <functional>.
#include <iostream>
#include <functional>

int add(int a, int b) { return a + b; }

int main() {
    std::function<int(int, int)> f = add;
    std::cout << f(2, 3) << '\n';
    return 0;
}

Przechowywanie lambdy

W przeciwieństwie do zwykłego wskaźnika do funkcji std::function bez problemu przechowuje lambdę, także taką z przechwytywaniem.

#include <iostream>
#include <functional>

int main() {
    int offset = 10;
    std::function<int(int)> f = [offset](int x) { return x + offset; };
    std::cout << f(5) << '\n';
    return 0;
}

Przechowywanie funktora

Funktor to obiekt zawierający operator(). std::function może go opakować i wywoływać jego operator podczas wywołania.

#include <iostream>
#include <functional>

struct Multiplier {
    int factor;
    int operator()(int x) const { return x * factor; }
};

int main() {
    std::function<int(int)> f = Multiplier{3};
    std::cout << f(4) << '\n';
    return 0;
}

Ponowne przypisywanie celu

Jedna zmienna typu std::function może w ciągu swojego życia wskazywać różne obiekty wywoływalne, co ułatwia wymianę zachowania w czasie działania programu.

#include <iostream>
#include <functional>

int main() {
    std::function<int(int)> f = [](int x) { return x + 1; };
    std::cout << f(10) << '\n';
    f = [](int x) { return x * x; };
    std::cout << f(10) << '\n';
    return 0;
}

Pusty std::function

Utworzony domyślnie obiekt std::function niczego nie przechowuje. Jego wywołanie powoduje zgłoszenie wyjątku std::bad_function_call, dlatego najpierw należy sprawdzić, czy nie jest pusty.

#include <iostream>
#include <functional>

int main() {
    std::function<void()> f;
    if (f) {
        f();
    } else {
        std::cout << "empty\n";
    }
    return 0;
}

Jako parametr

Funkcje mogą przyjmować parametr typu std::function, aby akceptować dowolny pasujący obiekt wywoływalny, co zwiększa elastyczność interfejsów API.

#include <iostream>
#include <functional>

void repeat(int n, const std::function<void(int)>& action) {
    for (int i = 0; i < n; ++i) action(i);
}

int main() {
    repeat(3, [](int i) { std::cout << "step " << i << '\n'; });
    return 0;
}

Przechowywanie funkcji zwrotnych

Częstym zastosowaniem jest przechowywanie funkcji zwrotnej jako składowej klasy, aby można ją było wywołać później, gdy wystąpi zdarzenie.

#include <iostream>
#include <functional>

struct Button {
    std::function<void()> onClick;
    void click() { if (onClick) onClick(); }
};

int main() {
    Button b;
    b.onClick = [] { std::cout << "clicked!\n"; };
    b.click();
    return 0;
}

Wektor obiektów wywoływalnych

Ponieważ mają wspólny typ, różne obiekty wywoływalne mogą być przechowywane razem w kontenerze i wywoływane kolejno.

#include <iostream>
#include <functional>
#include <vector>

int inc(int x) { return x + 1; }

int main() {
    std::vector<std::function<int(int)>> ops;
    ops.push_back(inc);
    ops.push_back([](int x) { return x * 2; });
    for (auto& op : ops) std::cout << op(10) << ' ';
    std::cout << '\n';
    return 0;
}

Koszt wymazywania typu

std::function może przydzielać pamięć i dodaje pośrednie wywołanie, dlatego jest nieco wolniejszy niż bezpośrednie wywołanie lub obiekt wywoływalny obsługiwany przez szablon. Należy go używać, gdy potrzebne jest jednolite przechowywanie.

#include <iostream>
#include <functional>

int main() {
    std::function<int()> f = [] { return 42; };
    int total = 0;
    for (int i = 0; i < 5; ++i) total += f();
    std::cout << total << '\n';
    return 0;
}

Zwracanie std::function

Fabryka może utworzyć i zwrócić skonfigurowany obiekt wywoływalny, umożliwiając kodowi wywołującemu uzyskanie niestandardowego zachowania.

#include <iostream>
#include <functional>

std::function<int(int)> adder(int n) {
    return [n](int x) { return x + n; };
}

int main() {
    auto add5 = adder(5);
    std::cout << add5(10) << '\n';
    return 0;
}

Porównanie ze wskaźnikami do funkcji

std::function jest bardziej elastyczny niż wskaźnik do funkcji, ponieważ przechowuje stan, ale ta elastyczność wiąże się z niewielkim spadkiem wydajności i możliwą alokacją.

#include <iostream>
#include <functional>

int main() {
    int base = 7;
    std::function<int(int)> stateful = [base](int x) { return x + base; };
    std::cout << "Stateful result: " << stateful(3) << '\n';
    return 0;
}

Szybkie sprawdzenie

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

Podsumowanie

Dowiedziałeś się, że std::function:

  • opakowuje dowolny obiekt wywoływalny zgodny z sygnaturą, w tym lambdy ze stanem i funktory
  • może być ponownie przypisywany, przechowywany w kontenerach i zwracany przez fabryki
  • zgłasza wyjątek bad_function_call, gdy jest pusty
  • wiąże się z niewielkim narzutem wynikającym z wymazywania typu

Następnie użyjesz std::bind do wstępnego przypisywania argumentów obiektom wywoływalnym.

Bezpłatny start

Ucz się C++ dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
51
Lekcje
203

Często zadawane pytania

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

Tak — pełny tekst „std::function” 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::function”?

Przechowuj dowolne obiekty wywoływalne Ć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 2 z 4.

Ile czasu zajmuje lekcja „std::function”?

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. Wskaźniki do funkcji
  2. std::function
  3. std::bind
  4. Wybór obiektów wywoływalnych
← Powrót do C++ Academy