когда надо передать или в std::transform как менять последовательность (то есть каждый элемент контейнера будет принудительно засовываться на вход функции-преобразователя), еще функция высшего порядка используется как предикат при сортировке или при поиске в последовательности и обычно такая функция, передаваемая алгоритму принимает или один или два параметра. А бывают еще какие нибудь случаи, когда в стандартный алгоритм надо передавать какую нибудь функцию, что принимает, допустим, три параметра ? Или в этом нет смысла никакого?
std::thread, std::invoke, std::bind
В каких ситуациях в целом лучше использовать std::bind вместо той же лямбды? Насколько я помню, std::bind не умеет даже в мув параметров в std::function
На сколько я понимаю, одно из применений bind - это если нам нужно пробросить аргументы куда либо без лишних затрат. Например аргументы в конструкор объекта при вызове emplace_back в векторе. То есть, если нам нужна такая обёртка над функцией, которая не делает ничего (реализовать такое не так тривиально, как кажется). Плюс, bind вариабельный шаблон использует, можно передавать туда нефиксированное количество элементов. А лямбда - это лямбда. Она создаёт замыкание. Если без захвата, то это больше похоже на указатель на функцию, если с захватом - то это похоже на объект, с состоянием и перегруженным оператором "operator()". Не понимаю последнего утверждения от слова совсем: вы говорите про мув параметров из std::bind в std::function? Если да, то зачем? Как будто бы это не имеет никакого смысла. Надеюсь более опытные участники чата меня поправят или дополнят, если где то не так сказал
Ни в каких, если уровень поддержки стандарта компилятором позволяет, а сейчас уже почти все компиляторы поддерживают 11ый
Функция высшего порядка при сортировке это не предикат сравнения, а сама сортировка, поэтому так и называется. srd::sort - функция высшего порядка, предикат - обычная функция. transform - ФЦП, функция преобразования одного элемента - обычная функция reduce - ФКП, и редуктор - обычная функция. По другому ещё (в С) это называется функция и callback- функция, как в find_first/next и call back для обработки одного файла. Поэтому если вам кто-то скажет, что C (чистый) не функциональный язык, не верьте, это не так.
Насчет С, да, это я знаю, что ты можешь передать имя функции, что равнозначно передаче указателя на функцию. Кстати, чем мне нравится С++ так это тем, что ты можешь у класса сделать "оператор функция", то есть ты можешь создать как бы вызываемый объект с состоянием (наполнить его какими то полезными данными), и потом уже вызвать его как функцию. Я сейчас изучаю С#, и там такого, блин нет... Я, если честно, в шоке. Вот человек, тоже в шоке, https://stackoverflow.com/questions/2450153/overloading-function-call-operator-in-c-sharp . В этом плане С++ даже более простой что ли...
в C# функции, с которыми можно работать как со значениями (записывать в переменные, соответственно, передавать в другие функции, хранить как состояние (поле) объекта, т.д.), называются делегатами. Один из стандартных делегатов в пространстве имен System — Func: Func<int, int, string> function = (x, y) => { return $"{x} + {y} = {x + y}"; }; Console.WriteLine(function(10, 2)); // 10 + 2 = 12 function = (x, y) => $"{x} * {y} = {x * y}"; Console.WriteLine(function(10, 2)); // 10 * 2 = 20 Работать с простым объектом класса как с функцией нельзя, хотя можно просто определить в нем функцию и вызвать 🤷🏼
нет, даже в C# "делегат" - это не сама функция, а именно специальный тип, хранящий ссылку на функцию.
это уже формальности реализации этой функциональности
так никто не заставляет огород городить — все нужные делегаты уже есть в System
"огород" - это именно букет этих System.Func (и то не на все случаи жизни, вдруг я захочу функцию с 20 аргументами? 🤡), которые являются (в терминологии C++) чем-то вроде явных инстанциирований шаблона. Ну и многие пользователи заводят свои делегаты с более строгой типизацией. Ну да ладно, прекращаю оффтопить
что значит "более строгая типизация"?
что ты хочешь завести именованный коллбэк с конкретными типами. Да, Func можно, но часто в библиотеках заводят свои типы.
> Да, Func туда подойдет, но часто в библиотеках заводят свои типы ну так пусть не заводят 🥲
на счет количества параметров да, типы делегатов System принимают до 16-ти. Если нужно больше, нужно написать свой, и делается это очень просто
блин, так я же и говорю, что это просто - за счет ключевого слова delegate, которое сгенерирует тип для тебя. По сути инстанциирует некую внутреннюю std::fuction от тех типов, которые ты просил.
Обсуждают сегодня