Является ли 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 для типа для хранения вызываемого объекта.)