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 — локальная установка не требуется.