Обычно, когда лямбда используется для "нисходящего" закрытия, вы можете преобразовать лямбду с ++ в блок clang, преобразовав:
[&](int i) { return i; }
до:
^(int i) { return i; }
Есть еще некоторые тонкие различия. Блоки Clang захватывают только классы C ++ по const. Я не знаю, включает ли это также C ++ POD типы.
Наконец, если необходимо «восходящее» закрытие, тогда они резко расходятся. Блоки Clang требуют, чтобы перехваченные переменные были помечены __block
, что компилятор разместит их в куче. Принимая во внимание, что в C ++ способ захвата лямбды должен определяться на основе времени жизни объекта (то есть путем создания копии или путем ссылки).
Также в C ++ копирование замыкания обрабатывается автоматически механизмом конструктора копирования в C ++. Однако для блока clang необходимо вызвать Block_copy
и Block_release
, чтобы обработать копирование блока. Для этого можно написать простую оболочку на C ++. Например:
typedef void (^simple_block)(void);
class block_wrapper
{
simple_block block;
public:
block_wrapper (const simple_block& x)
: block(Block_copy(x)) {}
void operator() () const
{
block();
}
block_wrapper(const block_wrapper& rhs)
: block(Block_copy(rhs.block))
{}
block_wrapper& operator=(const block_wrapper& rhs)
{
if (this != &rhs)
{
Block_release(this->block);
this->block = Block_copy(rhs.block);
}
return *this;
}
~block_wrapper ()
{
Block_release(this->block);
}
};