2017-04-27 45 views
3

我想收集lambda表達式,並要求不能複製lambas,只能移動。
這是因爲lambas可能需要移動捕捉一些不可複製構造的參數。std ::可移動lambda表達式的矢量,可能嗎?

例子:

NonCopyableType varName ; 
auto func = [a=move(varName)](){ ... } ; //varName is move-captured 

這個我想存儲funcvector後,但因爲它需要lambda表達式是可複製我不能使用std::function型。

vector<function<void()>> list ; 
list.push_back(func) ; //won't work 

是否有可能以其他方式做到這一點?

回答

3

當然。只需編寫您自己的function即可移動的克隆。下面是隻支持無參可調用的簡化版本,但你可以看到它如何擴展:

class move_function 
{ 
    struct placeholder { 
     virtual ~placeholder() = default; 
     virtual void call() = 0; 
    }; 

    template <class T> 
    struct holder : placeholder { 
     T f; 
     void call() override { f(); } 
    }; 

    std::unique_ptr<placeholder> f_; 

public: 
    template <class F, 
     class R = std::result_of_t<F&()>, 
     std::enable_if_t<!std::convertible<std::decay_t<F>*, move_function*>::value, int> = 0> 
    move_function(F&& f) 
     : f_(new std::decay_t<F>{std::forward<F>(f)}) 
    { } 

    void operator()() const { f_->call(); } 
}; 

所有隱含定義特殊的成員函數已經做正確的事情對我們來說。

+0

另請參閱[P0288](http://wg21.link/p0288)和[cxx_function庫](https://github.com/potswa/cxx_function)。 – Potatoswatter

+0

這讓我想知道爲什麼'std :: function'首先要求可複製性。 STL容器不需要它,並且與庫的其餘部分相配合。 – GetFree

+0

@GetFree類型擦除的原理要求類型提供「函數」所具有的所有功能。 'set '的默認構造函數不需要訪問'T'的拷貝構造函數。但是當你將'T'轉換爲'function '時,'T'的所有相關功能都需要立即捕獲,因爲'function'無法記住'T'。 – Potatoswatter