Почему std::bind1st можно считать почти непригодным для использования?

Во время разговора о boost::bind было отмечено, что std::bind1st существует в C++03, но "почти непригоден для использования".

Я не могу найти ничего твердого, чтобы поддержать это.

В в boost::bind документации говорится:

boost::bind — это обобщение стандартных функций std::bind1st и std::bind2nd. Он поддерживает произвольные функциональные объекты, функции, указатели на функции и указатели на функции-члены и может привязывать любой аргумент к определенному значению или направлять входные аргументы в произвольные позиции. bind не предъявляет никаких требований к объекту функции; в частности, ему не нужны стандартные определения типов result_type, first_argument_type и second_argument_type.

возможно, предполагается, что эти ограничения действительно применяются к std::bind1st.

Помимо очевидного ограничения на количество аргументов, в чем есть преимущества boost::bind перед std::bind1st/std::bind2nd? Есть ли смысл в утверждении, что std::bind1st «почти непригодна для использования» в C++03?


person Lightness Races in Orbit    schedule 07.07.2011    source источник


Ответы (2)


Если мы посмотрим на C++03 20.3.6.1 и 20.3.6.2, то увидим, что для аргумента функтора bind1st у нас есть требование трех typedef (для типа результата, первого и второго аргумента), и что результирующий оператор принимает только один аргумент.

Это означает, что мы не можем просто использовать bind1st для простых указателей функций, поскольку у них нет этих typedef. Также мы можем использовать bind1st только для бинарных функций, так как у нас нет поддержки дополнительных параметров. Кроме того, boost::bind et al имеют то преимущество, что могут изменять порядок параметров и, конечно же, поддерживают не только первый.

Мне кажется, что большинство вариантов использования связывателя — это свободные функции и функции-члены, а не объекты-функторы; как таковое использование bind1st довольно ограничено (хотя его можно расширить за счет использования других инструментов, таких как ptr_fun, но сомнительно, делает ли это более удобным). Конечно, это основано только на личном опыте, но кто-то может захотеть выполнить статистику поиска кода Google для bind1st.

person PlasmaHH    schedule 07.07.2011
comment
Обратите внимание, что ptr_fun решает первую проблему, предоставляя вам адаптируемую двоичную функцию, которая обертывает указанный указатель функции. Хотя остальное не решает. Позвонить ptr_fun легко, запомнить это немного сложнее ;-) - person Steve Jessop; 07.07.2011

Оператор вызова функции типа, который возвращает bind1st, является

typename Operation::result_type
operator()(const typename Operation::second_argument_type& x) const;

Это не будет работать со ссылочными параметрами связанного функционального объекта и очень строгим компилятором C++03 (более поздние выпуски менее строгие). C++03 запрещает ссылки на ссылки.

person Johannes Schaub - litb    schedule 07.07.2011
comment
Не должны ли ссылки свернуть? Я думаю, что читал что-то подобное для typedefs, то же самое с const. - person Xeo; 07.07.2011
comment
@Xeo не в С++ 03. Некоторые люди также используют его чтобы различать C++03 и C++0x, хотя с последними компиляторами это не будет работать. - person Johannes Schaub - litb; 07.07.2011