Как использовать bind1st и bind2nd?
Я хотел бы узнать, как использовать функции привязки.
Вот идея:
У меня есть эта функция, которая принимает параметры:
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
Я мог бы использовать функтор, но быстрее использовать привязку.
Спасибо!
Ответы
Ответ 1
Аргумент bind2nd
должен быть AdaptableBinaryFunction
. Обычная двоичная функция не удовлетворяет этому требованию (адаптивная функция требует typedefs для своих типов возвращаемых и аргументов, простой тип функции не предоставляет никаких typedefs). Вы можете использовать std::bind
, что, вероятно, лучший выбор.
Ответ 2
Вам нужно использовать объект 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
Ответ 3
Вам необходимо выполнить следующие действия:
1. создать структуру (или класс), которая наследуется от std:: binary_function
2. определить функцию предиката в функции-члене operator() структуры, созданной на шаге 1
3. используйте bind2nd для привязки соответствующего значения к структуре, созданной на шаге 1
Я сделал все это в одном примере. Вы можете прочитать статью и загрузить полный код по следующей ссылке: связать и найти