2012-03-10 5 views
2

次のコード:ラムダキャプチャから変数をキャプチャするとエラーが発生しますか? VS2010で

void AddBishopMoves(vector<Move> &moves, uint64_t mask, uint64_t occupied, uint64_t valid) 
{ 
    ForEachBit(mask, [&moves,occupied,valid](Square from) 
    { 
    auto toMask = BishopAttacks(from, occupied) & valid; 
    ForEachBit(toMask, [&moves, from](Square to) 
    { 
     moves.push_back(Move(from, to)); 
    }); 
    }); 
} 

はエラーに

エラーC3480を与える: '`匿名の名前空間' ::::に移動:ラムダ キャプチャ変数を囲んでからでなければなりません関数スコープ

しかし、私は外側のラムダで参照によって "動き"をキャプチャしました。

移動を一時的に割り当てるコードを変更し、一時的なキャプチャを実行するとエラーが解決されます。これはVS2010でエラーを起こさない:

void AddBishopMoves(vector<Move> &moves, uint64_t mask, uint64_t occupied, uint64_t valid) 
{ 
    ForEachBit(mask, [&moves,occupied,valid](Square from) 
    { 
    auto& x = moves; 
    auto toMask = BishopAttacks(from, occupied) & valid; 
    ForEachBit(toMask, [&x, from](Square to) 
    { 
     x.push_back(Move(from, to)); 
    }); 
    }); 
} 

質問はなぜですか?

コンパイラが私に警告しようとしているロジックの微妙なバグを避けていますか? これはC++ 11のキャプチャセマンティクスではサポートされていませんか? これはちょうど盗んだ機能ですか?

+1

コンパイラのバグのようです。とにかく信頼できないのはMSVS10です。それは解放された日に壊れています。 – Nawaz

+0

@Nawaz:ちょっとひどいですね。 MSVS10は完璧ではありませんが、ほとんどの場合、かなり良いです。私はバグのないコンパイラを使用していません。 –

+0

@BenjaminLindley:多分。しかし、今日使用されている他の主要なコンパイラと比較して、MSVS10にはより多くのバグがあります。したがって、コンパイラにバグが多い場合は、それを簡単に信頼することはできません。 – Nawaz

答えて

2

VS11ベータ版にはまだ遅れていますが、バグがまだ残っているので、これは修正済みと思われるa known bugです。

別の簡単な回避策はただ暗黙のうち内側のラムダで変数をキャプチャするために、次のようになります。

void AddBishopMoves(vector<Move> &moves, uint64_t mask, uint64_t occupied, uint64_t valid) 
{ 
    ForEachBit(mask, [&moves,occupied,valid](Square from) 
    { 
    auto toMask = BishopAttacks(from, occupied) & valid; 
    ForEachBit(toMask, [&, from](Square to) // <== implicit capture of 'moves' 
    { 
     moves.push_back(Move(from, to)); 
    }); 
    }); 
} 

私見私はいかなる理由が表示されないよう、あなたは一般的にだけ、参照することによって暗黙のうちに自分のものをキャプチャする必要がありますそれ以外の場合はこちらをご覧ください。

Btw、あなたのおかげで、私はanother bugを発見しました。これは関連している可能性があります。可能であればupvoteしてください。

関連する問題