Привязка к переменной-члену

Я не понимаю, что делает boost::bind, когда мы привязываемся к переменным-членам. При привязке к функции-члену мы, по сути, создаем объект функции, а затем вызываем его, передавая ему аргументы, которые предоставляются или задерживаются и заменяются с помощью заполнителей.

Но что это выражение делает за кадром:

boost::bind(&std::pair::second, _1); 

Что заменяется вместо заполнителя _1?

Я нашел это, читая этот пример из статьи о boost::bind:

void print_string(const std::string& s) {
  std::cout << s << '\n';
}

std::map<int,std::string> my_map;
my_map[0]="Boost";
my_map[1]="Bind";

std::for_each(
  my_map.begin(),
  my_map.end(),
   boost::bind(&print_string, boost::bind(
      &std::map<int,std::string>::value_type::second,_1)));

источник


person navigator    schedule 21.07.2009    source источник


Ответы (2)


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

int main()
{
   std::pair< int, int > p1 = make_pair( 1, 2 );
   std::pair< int, int > p2 = make_pair( 2, 4 );
   int std::pair<int,int>::*ptr = &std::pair<int,int>::second; // pointer to second member

   std::cout << p1.*ptr << std::endl; // 2 dereference pointer to member 
   std::cout << p2.*ptr << std::endl; // 4 dereference pointer to member
}

За кулисами bind составляет разные вызовы. Полученный функтор принимает разыменование std::map‹>::iterator (типа std::pair‹ const key_type, value_type >). Это передается внутренней привязке, которая разыменовывает указатель члена, таким образом возвращая (*it).second внешней привязке, которая передает это значение методу print_string для последнего вызова: print_string( (*it).second ).

(*it) на самом деле является _1, о котором вы спрашивали. Все _# являются заполнителями, то есть результатом bind будет функтор, который будет принимать столько аргументов, сколько различных заполнителей существует в порядке, определяемом номером заполнителя. В приведенном вами примере результирующий функтор принимает один аргумент _1.

person David Rodríguez - dribeas    schedule 21.07.2009

boost::bind(&std::pair<U,V>::second, _1);

функционально эквивалентен

std::pair<U,V> p -> p.second

т.е. это функция (объект), которая сопоставляет pair<U,V> своему члену second.

person Marc Mutz - mmutz    schedule 21.07.2009