Является ли std:: bind по-прежнему полезным по сравнению с lambdas?
Возможный дубликат:
Bind Vs Lambda?
Мое использование std::bind
упало до 0 теперь, когда lambdas получили широкую поддержку.
Существуют ли какие-либо проблемы, которые std::bind
однозначно подходят для лямбда-функции?
Была ли веская причина поддерживать std::bind
в стандарте после добавления lambdas?
Ответы
Ответ 1
Вы можете записывать по значению или по ссылке, и проблема в том, что захват по значению действительно означает "захват копией". Это шоу-стоппер для типа движения. Поэтому вы не можете использовать lambda для выполнения следующих действий:
struct foo { void bar() {} };
std::unique_ptr<foo> f { new foo };
auto bound = std::bind(&foo::bar, std::move(f));
static_assert( std::is_move_constructible<decltype(bound)>::value, "" );
bound();
IIRC. В стандартном комитете вкратце рассматривается возможность произвольного выражения внутри списка захвата лямбда для решения этой проблемы (которая может выглядеть как [std::move(f)] { return f.bar(); }
), но я не думаю, что было твердое предложение, и С++ 11 уже задерживался.
Это и ограничение на мономорфное поведение с lambdas являются нарушителями сделки для меня.
Ответ 2
bind
отлично подходит для создания ссылок на связанную функцию-член:
Foo x;
auto f = std::bind(&Foo::bar, &x, 12, true);
register_callback(f);
Изменить: Как показывает Люк Дантон, эта конструкция очень гибкая и позволяет указателю экземпляра прийти к удивительному множеству обличий (например, интеллектуальные указатели). [/]
Если возможно, желательно, чтобы лямбда была предпочтительнее, тем более что она дает больший потенциал для оптимизации, но привязки-выражения все еще имеют свое место.
(В любом случае auto
предпочтительнее std::function
для типа для хранения вызываемого объекта.)