[英]How to capture std::unique_ptr “by move” for a lambda in std::for_each
我正在學習c ++ 11中的新功能並遇到了這個問題。 我想通過在lambda中移動它作為for_each的參數來捕獲unique_ptr。
設定:
std::array<int,4> arr = {1,3,5,6};
std::unique_ptr<int> p(new int); (*p) = 3;
嘗試1 - 不起作用,因為unique_ptr沒有復制構造函數。 c ++ 0x沒有指定移動語法。
std::for_each(arr.begin(), arr.end(), [p](int& i) { i+=*p; });
嘗試2 - 使用bind將p的移動副本綁定到一個帶有int&的函數:
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p))
);
編譯器抱怨'result' : symbol is neither a class template nor a function template.
這個練習的主要目的是了解如何在lambda中捕獲可移動變量,該lambda被緩存以供以后使用。
更新:您可以從C ++ 14開始捕獲lambda中的可移動變量。
std::for_each(arr.begin(), arr.end(), [p=std::move(p)](int& i) { i+=*p; });
在C ++ 11中,您無法以任何直接的方式將可移動變量捕獲到lambda中。
通過復制或引用捕獲Lambda。 因此,要捕獲僅移動變量,必須將其包裝在復制=>移動的對象(例如std::auto_ptr
)中。 這是一個討厭的黑客。
在您的示例中,您可以通過引用捕獲,但如果這只是簡化的代碼,它可能無法使用實際代碼執行您想要的操作:
std::for_each(arr.begin(), arr.end(), [&p](int& i) { i+=*p; });
這是一個僅復制移動的包裝器:
template<typename T>
struct move_on_copy_wrapper
{
mutable T value;
move_on_copy_wrapper(T&& t):
value(std::move(t))
{}
move_on_copy_wrapper(move_on_copy_wrapper const& other):
value(std::move(other.value))
{}
move_on_copy_wrapper(move_on_copy_wrapper&& other):
value(std::move(other.value))
{}
move_on_copy_wrapper& operator=(move_on_copy_wrapper const& other)
{
value=std::move(other.value);
return *this;
}
move_on_copy_wrapper& operator=(move_on_copy_wrapper&& other)
{
value=std::move(other.value);
return *this;
}
};
然后你可以像這樣使用它:
int main()
{
std::unique_ptr<int> p(new int(3));
move_on_copy_wrapper<std::unique_ptr<int>> mp(std::move(p));
[mp]()
{
std::cout<<"*mp.value="<<*mp.value<<std::endl;
}
();
std::cout<<"p="<<p.get()<<", mp="<<mp.value.get()<<std::endl;
}
你的嘗試2幾乎可以工作。
缺少的是你沒有告訴你的bind
調用期望一個參數:
std::for_each(arr.begin(), arr.end(),
std::bind([](const unique_ptr<int>& p, int& i){
i += (*p);
}, std::move(p), std::placeholders::_1)
);
placeholders::_1
必須告訴bind
的結果,它應該期望為其operator()
傳遞給它的參數。
這也是@ marton78 在這里給出的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.