0Pricing
C++ Academy · Урок

std::bind

Привязывайте аргументы к вызываемым объектам

«std::bind» — бесплатный урок C++ Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Что такое std::bind?

std::bind создает новый вызываемый объект, фиксируя некоторые аргументы существующего объекта. Это называется частичным применением.

  • Определен в <functional>.
  • Возвращает вызываемый объект неуказанного типа.
#include <iostream>
#include <functional>

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

int main() {
    auto add10 = std::bind(add, 10, 5);
    std::cout << add10() << '\n';
    return 0;
}

Заполнители

Заполнители, такие как std::placeholders::_1, обозначают аргументы, которые будут переданы позже при вызове связанного объекта.

#include <iostream>
#include <functional>

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

int main() {
    using namespace std::placeholders;
    auto add10 = std::bind(add, 10, _1);
    std::cout << add10(7) << '\n';
    return 0;
}

Изменение порядка аргументов

Заполнители могут располагаться в любом порядке, позволяя менять местами позиции аргументов, передаваемых вызывающим кодом.

#include <iostream>
#include <functional>

int sub(int a, int b) { return a - b; }

int main() {
    using namespace std::placeholders;
    auto flipped = std::bind(sub, _2, _1);
    std::cout << flipped(3, 10) << '\n';
    return 0;
}

Связывание нескольких аргументов

Можно одновременно зафиксировать несколько аргументов, оставив остальные заполнителями.

#include <iostream>
#include <functional>

int volume(int l, int w, int h) { return l * w * h; }

int main() {
    using namespace std::placeholders;
    auto box = std::bind(volume, 2, _1, 5);
    std::cout << box(3) << '\n';
    return 0;
}

Сохранение результата

Объект, возвращенный std::bind, можно сохранить в std::function, получив конкретный именованный тип.

#include <iostream>
#include <functional>

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

int main() {
    using namespace std::placeholders;
    std::function<int(int)> add100 = std::bind(add, 100, _1);
    std::cout << add100(1) << '\n';
    return 0;
}

Связывание функций-членов

std::bind может обратиться к функции-члену, если передать указатель на член и объект (или заполнитель) для this.

#include <iostream>
#include <functional>

struct Counter {
    int add(int x) { return value += x; }
    int value = 0;
};

int main() {
    using namespace std::placeholders;
    Counter c;
    auto bump = std::bind(&Counter::add, &c, _1);
    std::cout << bump(5) << ' ' << bump(3) << '\n';
    return 0;
}

Связывание по значению и по ссылке

Связанные аргументы по умолчанию копируются. Оберните один из них в std::ref, чтобы связать его по ссылке и сделать изменения видимыми.

#include <iostream>
#include <functional>

void addTo(int& target, int amount) { target += amount; }

int main() {
    using namespace std::placeholders;
    int total = 0;
    auto acc = std::bind(addTo, std::ref(total), _1);
    acc(5);
    acc(10);
    std::cout << total << '\n';
    return 0;
}

Использование связанных вызываемых объектов в алгоритмах

Связанный вызываемый объект работает как предикат или операция в стандартных алгоритмах.

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

bool greaterThan(int x, int limit) { return x > limit; }

int main() {
    using namespace std::placeholders;
    std::vector<int> v = {1, 5, 8, 2, 9};
    auto over4 = std::bind(greaterThan, _1, 4);
    std::cout << std::count_if(v.begin(), v.end(), over4) << '\n';
    return 0;
}

Вложенные вызовы bind

Выражения bind можно компоновать, хотя результат быстро становится трудным для чтения. Каждый заполнитель по-прежнему относится к аргументам конечного вызывающего кода.

#include <iostream>
#include <functional>

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

int main() {
    using namespace std::placeholders;
    auto f = std::bind(add, std::bind(times, 2, _1), 3);
    std::cout << f(5) << '\n';
    return 0;
}

Игнорирование лишних аргументов

Если связанный вызов использует только некоторые заполнители, любые дополнительные аргументы, переданные во время вызова, просто игнорируются.

#include <iostream>
#include <functional>

int show(int a) { return a; }

int main() {
    using namespace std::placeholders;
    auto f = std::bind(show, _1);
    std::cout << f(42, 99, 100) << '\n';
    return 0;
}

Когда лямбда понятнее

В современном C++ часто предпочитают лямбду вместо std::bind, поскольку она понятнее, а компилятор лучше её оптимизирует.

#include <iostream>
#include <functional>

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

int main() {
    auto add10 = [](int x) { return add(10, x); };
    std::cout << add10(5) << '\n';
    return 0;
}

Быстрая проверка

Проверьте своё понимание заполнителей.

Повторение

Вы узнали, как работает std::bind:

  • фиксирует некоторые аргументы и использует заполнители _1, _2 для остальных
  • может менять порядок аргументов, связывать функции-члены и использовать std::ref
  • результаты можно сохранять в std::function и использовать в алгоритмах
  • в современном C++ лямбды часто понятнее

Далее Вы сравните лямбды, bind и указатели на функции, чтобы выбрать подходящий инструмент.

Часто задаваемые вопросы

Урок «std::bind» бесплатный?

Да — полный текст урока «std::bind» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «std::bind»?

Привязывайте аргументы к вызываемым объектам Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «std::bind»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Указатели на функции
  2. std::function
  3. std::bind
  4. Выбор вызываемых объектов
← Назад к C++ Academy