2017-08-18 67 views
1

是否可以通過在一個lambda中捕獲它並延長lambda的壽命來延長unique_ptr的壽命?通過延長捕獲的壽命來保留指針

我試過了,但得到了a=move(a)表達式的語法錯誤。

#include <cstdio> 
#include <functional> 
#include <memory> 
#include <iostream> 

using namespace std; 

struct A { 
    A() { cout << "A()" << endl; } 
~A() { cout << "~A()" << endl; } 
}; 

int main() { 
    std::function<void()> f; 
    { 
    std::unique_ptr<A> a(new A()); 
    f = [a=move(a)]() mutable { return; }; 
    } 
    return 0; 
} 
+1

你可以在lambda中捕獲對象,除非它們可複製,因爲lambda是可複製的,構造函數被刪除了unique_ptr,編譯器也刪除了你的lambda – Swift

回答

1

那麼你的代碼的問題是std::function。它不是非常友好的動作,因爲它需要可調用的可複製/可分配,因爲您的lambda不是因爲僅使用了移動類型unique_ptr

有很多例子可以爲您提供移動友好版本std::function

我來到這裏有一個快速的,哈克,而且可能容易出錯,但「我的機器上工作」的版本相同的:

#include <memory> 
#include <iostream> 
#include <type_traits> 


struct A { 
    A() { std::cout << "A()" << std::endl; } 
~A() { std::cout << "~A()" << std::endl; } 
}; 

template <typename Functor> 
struct Holder 
{ 
    static void call(char* sbo) { 
     Functor* cb = reinterpret_cast<Functor*>(sbo); 
     cb->operator()(); 
    } 

    static void deleter(char* sbo) { 
     auto impl = reinterpret_cast<Functor*>(sbo); 
     impl->~Functor(); 
    } 

}; 

template <typename Sign> struct Function; 

template <> 
struct Function<void()> 
{ 
    Function() = default; 
    ~Function() { 
     deleter_(sbo_); 
    } 

    template <typename F> 
    void operator=(F&& f) 
    { 
     using c = typename std::decay<F>::type; 
     new (sbo_) c(std::forward<F>(f)); 
     call_fn_ = Holder<c>::call; 
     deleter_ = Holder<c>::deleter; 
    } 

    void operator()() { 
     call_fn_(sbo_); 
    } 

    typedef void(*call_ptr_fn)(char*); 
    call_ptr_fn call_fn_; 
    call_ptr_fn deleter_; 
    char sbo_[256] = {0,}; 
}; 

int main() { 
    Function<void()> f; 
    { 
     std::unique_ptr<A> a(new A()); 
     f = [a=move(a)]() mutable { return; }; 
    } 
    std::cout << "Destructor should not be called before this" << std::endl; 
    return 0; 
} 

要嘗試一下自己: http://coliru.stacked-crooked.com/a/60e1be83753c0f3f

+0

我明白了,實際上你需要不同的持有者類型,謝謝你解釋這個! – foobarometer