一般に、ラムダが「下方」クロージャーに使用される場合、次のように変換することで、c++ ラムダを clang ブロックに変換できます。
[&](int i) { return i; }
に:
^(int i) { return i; }
まだいくつかの微妙な違いがあります。Clang のブロックは、const によって C++ クラスのみをキャプチャします。これに C++ POD タイプも含まれているかどうかはわかりません。
最後に、「上向き」の閉鎖が必要な場合、この 2 つは大幅に異なります。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);
}
};