[問題] std::bind + lambda + move-only object

作者: dreamboat66 (小嫩)   2016-11-30 23:21:12
如果在C++ 11 lambda想要move capture 似乎只能用一些手腳
於是我就好奇的做了一些測試
http://ideone.com/99S4Qx
大概分成三個問題(如code所列)
1. 這個最單純, 一般認知std bind回傳的物件可以用 std::function來接
但我這樣寫 怎麼樣都接不起來 似乎只能用auto讓他自己判斷, 為什麼呢?
2. 用了auto來寫 接了以後想要invoke看看, 誰知道遇到怪事
(a) lambda參數寫 const unique_ptr<int>& uptr2 後 就可以呼叫func2(這勉強可以接受)
(b) 參數寫 unique_ptr<int>& uptr2 竟然可以吃 std::move的rvalue ref
(這感覺內部實做還是by lvalue傳遞, 但又沒有std::rref 整個有點怪)
(c) 寫 unique_ptr<int>&& uptr2 或是 unique_ptr<int> uptr2 只要寫了func2() 就會
compile error...這我就不知道為什麼了
3. 也就是上面(c)的問題, 我是不是就不能呼叫了?
以上麻煩各位提供一些意見 釐清觀念
謝謝
作者: Caesar08 (Caesar)   2016-11-30 23:49:00
關於2、3,標準的確是定義bind內部呼叫func是當l value所以2、3不能通過編譯是正確的
作者: dreamboat66 (小嫩)   2016-11-30 23:57:00
但至少unique_ptr<int> uptr2應該可吧?
作者: Caesar08 (Caesar)   2016-11-30 23:59:00
unique_ptr是個move only的object阿...
作者: dreamboat66 (小嫩)   2016-12-01 00:05:00
阿阿~~了解
作者: Caesar08 (Caesar)   2016-12-01 00:05:00
然後1有點複雜bind的return type,只有當所有的parameter type都為copyable的時候,return type才能被copy。但是std::function的constructor是用copy f的方式,所以不能通過編譯。然後std::function的operator=會呼叫constructor。(前後關係寫顛倒了)對了,所有的parameter type也包含f的型態
作者: dreamboat66 (小嫩)   2016-12-01 23:52:00
了解了 謝謝~~原來return type還可以不被spec定義

Links booklink

Contact Us: admin [ a t ] ucptt.com