Обновление: я был не прав, вот почему он действительно работает * Параметр шаблона
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
не была специально обновлена для поддержки блоков)