Когда следует использовать std:: bind?
Каждый раз, когда мне нужно использовать std::bind
, я в конечном итоге использую лямбда. Итак, когда следует использовать std::bind
? Я только что закончил удаление его из одной кодовой базы, и я обнаружил, что лямбды всегда были проще и понятнее, чем std::bind
. Разве не std::bind
совершенно не нужно? Разве это не должно быть устаревшим в будущем? Когда я предпочитаю std::bind
лямбда-функциям? (Должна быть причина, что он попал в стандарт одновременно с лямбдами.)
Я также заметил, что все больше и больше людей знакомы с лямбдами (поэтому они знают, что делают лямбды). Однако гораздо меньше людей знакомы с std::bind
и std::placeholders
.
Ответы
Ответ 1
Здесь вы ничего не можете сделать с лямбдой:
std::unique_ptr<SomeType> ptr = ...;
return std::bind(&SomeType::Function, std::move(ptr), _1, _2);
Lambdas не может захватывать типы только для перемещения; они могут захватывать только значения по копиям или по ссылке lvalue. Хотя, по общему признанию, это временная проблема, которая активно разрешена для С++ 14;)
"Упрощение и ясность" - это вопрос мнения. Для простых случаев привязки bind
может потребоваться намного меньше ввода. bind
также фокусируется исключительно на привязке функций, поэтому, если вы видите std::bind
, вы знаете, что вы смотрите. Если вы используете лямбда, вам нужно взглянуть на реализацию лямбда, чтобы быть уверенным в том, что она делает.
Наконец, С++ не осуждает вещи только потому, что какая-то другая функция может делать то, что она делает. auto_ptr
устарел, потому что он по своей сути опасен для использования, и существует неопасная альтернатива.
Ответ 2
Вы можете создавать полиморфные объекты с std::bind
, которые вы не можете использовать с lambdas, т.е. оболочка вызова, возвращаемая std::bind
, может быть вызвана с разными типами аргументов:
#include <functional>
#include <string>
#include <iostream>
struct Polly
{
template<typename T, typename U>
auto operator()(T t, U u) const -> decltype(t + u)
{ return t + u; }
};
int main()
{
auto polly = std::bind(Polly(), std::placeholders::_1, "confusing");
std::cout << polly(4) << polly(std::string(" this is ")) << std::endl;
}
Я создал это как головоломку, не являющийся примером хорошего кода, но он демонстрирует полиморфные оболочки вызова.