Как использовать bind1st и bind2nd? - PullRequest
16 голосов
/ 14 сентября 2009

Я хотел бы узнать, как использовать функции привязки. Вот идея: У меня есть эта функция, которая принимает параметры:

void print_i(int t, std::string separator)
{
        std::cout << t << separator;
}

И я бы хотел сделать:

std::vector<int> elements;
// ...
for_each(elements.begin(), elements.end(), std::bind2nd(print_i, '\n'));

Но это не работает!

Вот что я получаю:

/usr/include/c++/4.3/backward/binders.h: In instantiation of ‘std::binder2nd<void ()(int, std::string)>’:
main.cpp:72:   instantiated from here
/usr/include/c++/4.3/backward/binders.h:138: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:141: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:145: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:149: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:155: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/backward/binders.h:140: error: field ‘std::binder2nd<void ()(int, std::string)>::op’ invalidly declared function type
/usr/include/c++/4.3/backward/binders.h: In function ‘std::binder2nd<_Operation> std::bind2nd(const _Operation&, const _Tp&) [with _Operation = void ()(int, std::string), _Tp = char]’:
main.cpp:72:   instantiated from here
/usr/include/c++/4.3/backward/binders.h:164: error: ‘void ()(int, std::string)’ is not a class, struct, or union type
/usr/include/c++/4.3/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >, _Funct = std::binder2nd<void ()(int, std::string)>]’:
main.cpp:72:   instantiated from here
/usr/include/c++/4.3/bits/stl_algo.h:3791: error: no match for call to ‘(std::binder2nd<void ()(int, std::string)>) (int&)’
make: *** [all] Error 1

Я мог бы использовать функтор, но быстрее использовать связывание.

Спасибо!

Ответы [ 4 ]

26 голосов
/ 14 сентября 2009

Вам необходимо использовать объект Copyable / Refrencable, работает следующее:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>

void print_i(int t, std::string separator)
{
   std::cout << t << separator;
}

int main()
{
   std::vector<int> elements;
   std::string delim = "\n";
   for_each(elements.begin(), 
            elements.end(),
            std::bind2nd(std::ptr_fun(&print_i),delim));
   return 0;
}

Обычно вы можете получить тот же эффект, просто выполнив следующее:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
   std::vector<int> elements;
   std::copy(elements.begin(),
             elements.end(),
             std::ostream_iterator<int>(std::cout,"\n"));
   return 0;
}

Также при условии, что у вас есть доступ к TR1 в используемом STL, всегда лучше пересмотреть / заменить любое использование bind1st и bind2nd на std :: bind

11 голосов
/ 14 сентября 2009

Аргумент для bind2nd должен быть AdaptableBinaryFunction.Простая бинарная функция не удовлетворяет этому требованию (адаптируемая функция требует typedefs для своих типов возврата и аргументов, простой тип функции не предоставляет никаких typedefs).Вы можете использовать std::bind, что, пожалуй, лучший выбор.

3 голосов
/ 06 ноября 2010

Вам необходимо выполнить следующие шаги:
1. создать структуру (или класс), которая наследуется от std :: binary_function
2. определите свою функцию предиката в функции-члене operator () структуры, созданной на шаге 1
3. используйте bind2nd для привязки подходящего значения к структуре, созданной на шаге 1

Я сделал все это на примере. Вы можете прочитать статью и скачать полный код по следующей ссылке: связать и найти

1 голос
/ 27 августа 2018

Эти функции устарели с C ++ 11 и удалены в C ++ 17. Как упомянуто в одном комментарии выше, лучшее решение сейчас состоит в использовании std::bind и заполнителей:

void callable(int a, int b);
auto f = std::bind1st(&callable, 42); // returns a 1-arg function

становится:

// returns a 1-arg function
auto f = std::bind(&callable, 42, std::placeholders::_1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...