reference_closureの継承
http://d.hatena.ne.jp/Cryolite/20080328#p1
のk.inabaさんのコメントにあるようにN2529に書いてありました。
オーバーロードの解決のためだったんですね。
懸念された最適化の問題も、
class F : public std::reference_closure<int (int)> { private: typedef std::reference_closure<int (int)> base_type; public: // reference_closureから復元用 explicit F(void* frame) : base_type(&F::invoke, frame) , count(*(static_cast<int*>(frame) - 2)) // [ EBP - 8] { } // ラムダ式用 F(void* frame, int& count) : base_type(&F::invoke, frame) , count(count) { } // ... };
のように局所変数を直接渡すコンストラクタを用意すれば、reference_closureにコピーしない限りはインライン化されました。
reference_closureへコピーした際のスライシングもこの場合は望ましい挙動です。
これで一件落着と思いきや、気になるのはADLです。
void foo(const int* beg, const int* end) { int a = 0; // OK: クロージャはstd::reference_closure<int(int)>を継承している for_each(beg, end, [&a](int n){ return a+n; }); // エラー: クロージャはstd::reference_closure<int(int)>を継承していない for_each(beg, end, [a](int n){ return a+n; }); // これならOK std::for_each(beg, end, [a](int n){ return a+n; }); }
キャプチャする内容によって関連名前空間が違ってくるのはトラブルの元になりそうな気がします。