Почему std :: tr1 :: function работает с блоками Objective-C? - PullRequest
10 голосов
/ 09 апреля 2011

Я был довольно удивлен, когда обнаружил, что на самом деле работает следующий код:

std::vector<int> list /*= ...*/;
std::tr1::function<void(int)> func = ^(int i) {
  return i + 1;
};

std::for_each(list.begin(), list.end(), func);

Похоже, что std::tr1::function может быть построен из блока Objective-C, но я не совсем уверен, как, поскольку (последний раз я проверял), его реализация специально не обрабатывает блоки. Это как-то неявно высасывает указатель на базовую функцию? Кроме того, это поведение не определено и может измениться?

Ответы [ 2 ]

6 голосов
/ 17 апреля 2011

Обновление: я был не прав, вот почему он действительно работает * Параметр шаблона

std::tr1::function просто определяет подпись результирующего функционального объекта, а нетип, который он на самом деле оборачивает.Таким образом, обернутый объект должен только предложить operator() с соответствующей подписью.Блочные ссылки, как и указатели на функции, имеют такой operator() неявно (очевидно, что вы можете их вызывать).

Старый, неправильный ответ (поэтому комментарии имеют смысл)

Я сильно подозреваю, что это работает, потому что блок не захватывает никакие переменные из окружающей области видимости.В этом случае нет состояния для поддержки, поэтому ссылка на блок может быть представлена ​​как пустой указатель на функцию.Если мы изменим код на

std::vector<int> list /*= ...*/;
int counter = 0;
std::tr1::function<void(int)> func = ^(int i) {
  counter++;
  return i + counter;
};

std::for_each(list.begin(), list.end(), func);

, он не сможет скомпилироваться, так как блок должен содержать захваченное значение counter вместе с ним.(если, конечно, реализация std::tr1::function не была специально обновлена ​​для поддержки блоков)

0 голосов
/ 17 апреля 2011

Хотя вы можете рассматривать блоки как объекты Objective-C и Objective-C имеет большую поддержку блоков, блоки не ограничиваются Objective-C. Вы также можете использовать блоки в C и C ++. См. эту статью для получения дополнительной информации.

...