|
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
|
||||||
Как работает std::bind?11.10.2024, 19:08. Показов 1217. Ответов 11
Метки нет (Все метки)
Приветствую. Вопрос собственно в следующем: как я понял placeholders в bind указывает какой аргумент взять при вызове из оператора скобки и посдатвить в функцию. Т.е bind(f, 2222, placeholders::_2)(3333, 4444);, здесь если placeholders::_2, то это равносильно f(2222, 4444), а если placeholders::_1, то равносильно f(2222, 3333); В коде ниже есть функция f(int, int) и пример бинда с ней.
Но, так же в примере есть класс Base с методом show(), который аргументов вообще не принимает и в мэйне for_each(v.begin(), v.end(), bind(&Base::show, placeholders::_1));, но тогда мне не понятно, для чего используется placeholders::_1 в случае когда аругументов у функции, которая отправляется в бинд нету? И получается, с помощью бинда можно создавать функтор как с большим количеством аргументов, чем у изначальной функции, так и с меньшим?
0
|
||||||
| 11.10.2024, 19:08 | |
|
Ответы с готовыми решениями:
11
Как можно еще использовать std::placeholders вне в связки с std::bind?
Накладные расходы std::function, std::bind, анонимные функции |
|
87 / 87 / 18
Регистрация: 11.06.2018
Сообщений: 302
|
|
| 11.10.2024, 19:11 | |
|
1
|
|
|
Заблокирован
|
|||
| 11.10.2024, 19:36 | |||
|
Добавлено через 13 минут
0
|
|||
|
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
|
||
| 11.10.2024, 19:44 [ТС] | ||
|
0
|
||
|
Заблокирован
|
|||||||||||||||||
| 11.10.2024, 20:06 | |||||||||||||||||
|
Добавлено через 3 минуты bind - это конструкт, который создает функтор, в его конструкторе описываются сами связи.
Пример с большим количеством аргументов :
И ещё :
1
|
|||||||||||||||||
|
Вездепух
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
|
|||||||||
| 11.10.2024, 23:09 | |||||||||
Сообщение было отмечено Ballantrae как решение
Решениеstd::bind используют так, чтобы у результирующего функтора был компактный и непрерывный (с точки зрения нумерации) набор аргументов. Но если вам приспичило заняться именно "выхватыванием" отдельных разрозненных аргументов из избыточного набора - то так тоже можно.Base::show() в вашем примере есть параметр. В этом случае функция является нестатическим методом класса, а это значит, что с точки зрения std::bind ее первый параметр - это указатель this. То есть у нее есть неявный параметр Base *this. Именно в него и будет передаваться аргумент, обозначенный placeholders::_1 в вашем случае. Если бы у show были явные параметры, то они бы являлись вторым, третьим и т.д. параметрами.То есть вашем примере bind(&Base::show, std::placeholders::_1) фактически "ничего не делает", кроме того, что превращает/конвертирует метод класса (т.е. функцию с неявным параметром) в функтор с одним явным параметром. "Фиксации" каких-то параметров не происходит вообще: как был один параметр, так и остался. Но теперь такой функтор может вызываться обычным синтаксисом вызова функции, а не специальным синтаксисом вызова метода класса.У полученного в результате функтора есть еще одно замечательное свойство: в качестве аргумента он может принимать как указатель, так и ссылку. В обоих случаях он правильно вызовет метод:
Никаких проблем с bind(&Base::show, placeholders::_2) нет. Все прекрасно компилируется, не надо выдумывать.А "не будет компилироваться" - это если позже, в точке вызова функтора, вы укажете аргументов меньше, чем нужно. О каком "втором аргументе" может идти речь, если в точке вызова вы указали только один аргумент? Неудивительно, что вызов не будет компилироваться. В точке вызова можно указывать больше аргументов, чем нужно. Но указывать меньше, чем нужно, нельзя.
0
|
|||||||||
|
518 / 368 / 65
Регистрация: 09.03.2016
Сообщений: 3,890
|
||||||
| 11.10.2024, 23:26 | ||||||
|
https://habr.com/ru/articles/310270/
А я ни чё не понял. Вы все умные, а я не очень. Помню я извращённый синтаксис boost... Я что то даже изобретал на нём. Клиент-сервер. Добавлено через 9 минут
0
|
||||||
|
Вездепух
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
|
||
| 12.10.2024, 03:13 | ||
std::mem_fn. То есть вместо такого bind можно было написать намного короче - std::mem_fn(&Base::show) - и получить тот же самый эффект.
0
|
||
|
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
|
||
| 12.10.2024, 11:50 [ТС] | ||
|
0
|
||
|
Вездепух
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
|
||
| 12.10.2024, 19:45 | ||
bind(&Base::show, placeholders::_1)) placeholders::_2 - это bind(&Base::show, placeholders::_1, placeholders::_2)В любом случае, подытоживая, если говорить о соответствии количества параметров, то проверки времени компиляции сводятся к следующему: 1. В точке выполнения std::bind количество указанных подстановок для параметров должно быть равно количеству параметров используемой функции. То есть для каждого параметра (включая неявный this) должно быть указано либо связывающее значение, либо placeholder, либо вложенный bind. 2. В точке вызова количество указанных аргументов должно быть не меньше чем максимальный номер использованного placeholder. При этом если задача состоит просто в том, чтобы, как в вашем примере с Base::show, превратить метод класса в обычный функтор (не манипулируя параметрами), то std::mem_fn для этой цели пользоваться удобнее, ибо в нем вообще не нужно думать о параметрах. Хотя во время выполнения и std::mem_fn, и std::bind будут менее эффективными, чем лямбда в той же роли.
1
|
||
|
1 / 1 / 0
Регистрация: 06.05.2021
Сообщений: 242
|
||||||
| 14.10.2024, 12:40 [ТС] | ||||||
|
TheCalligrapher, спасибо, суть вроде уловил. Хотя не всё ещё понятно. У меня в рабочем коде используется boost log, и написан класс, который должен то что выводится в лог, выводить так же и в виджет внутри программы. Рабочий код я показать не могу, но я написал аналогичный кусок, что бы повторить в упрощённом виде, без буста, рабочий код и разобраться как он работает. Тут не всё, что в рабочем коде, там ещё используется boost::shared_ptr<logger_boost_notifier_ t> ptr = boost::make_shared<logger_boost_notifier _t>(tb_ptr)Но так как я без буста хотел повторить часть кода, то этой строки у меня нет. Вот он:
1) Что происходит в строке tb_ptr = boost::make_shared<TestBase>(bind(&TestP rint: rint_log_str, this, std: laceholders::_1)); (никак не разберусь, как выделять строку с кодом в тексте)Тут я присваиваю значение tb_ptr, это понятно. Но как возврат бинда превращается в shared_ptr (я не про make_shared), а про то - что bind возвращает? Объект функтор наверно ведь? Но как он может в итоге стать shared_ptr да ещё и на другой класс? 2) Зачем явно передаётся this? 3) В бинд я передаю указатель на функцию, но ведь имя функции это и есть указатель на неё, по этому мне не понятно, почему перед TestPrint: rint_log_str мне нужно указывать &?
0
|
||||||
|
Вездепух
12928 / 6796 / 1819
Регистрация: 18.10.2014
Сообщений: 17,197
|
|||||||||
| 14.10.2024, 20:03 | |||||||||
shared_ptr создается только через make_shared. Больше нигде.)make_shared<T> создает объект типа T, то есть именно того типа, который указан в треугольных скобках. То есть ваш boost::make_shared<TestBase> создает объект типа TestBase и возвращает shared_ptr именно на новый объект типа TestBase. Не на результат bind, как вы почему-то подумали, а именно на новый объект типа TestBase.А обычные параметры функции, указанные в круглых скобках, лишь используются в качестве параметров конструктора для создаваемого объекта. То есть в вашем случае результат bind не имеет никакого отношения к shared_ptr и никак в него не "превращается". Результат bind будет просто передан в конструктор создаваемого TestBase. То есть результат bind превратится в std::function<>, т.е. в str_print_callback.Так работает make_shared.--- То есть ваше tb_ptr = make_shared<TestBase>(bind(&TestPrint::print_log_str, this, std::placeholders::_1)) - это аналог (по шагам)
TestPrint::print_log_str имеет два параметра: неявный ("невидимый") параметр this и явный параметр str. Нам нужно превратить этот метод в str_print_callback, который имеет один параметр. То есть один параметр нам надо будет исключить ("связать") при помощи bind.Это мы и делаем. Первый (неявный) параметр TestPrint::print_log_str мы "связываем" при помощи bind: в качестве аргумента мы подставляем значение this, то есть этот связанный параметр будет указывать на тот самый объект, который создал этот функтор. А второй параметр мы оставляем "свободным". В результате мы получаем функтор с одним параметром, как нам и нужно.&Class::method. Все надо явно писать целиком, включая &.
1
|
|||||||||
| 14.10.2024, 20:03 | |
|
Помогаю со студенческими работами здесь
12
В чем отличия между std::cref() и std::bind()? std::bind
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
|
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод
Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод.
Thinkpad X220 Tablet —. . .
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|