Capture and move a unique_ptr in a c++14 lambda expression

后端 未结 3 903
夕颜
夕颜 2021-02-01 01:44

I am capturing a unique_ptr in a lambda expression this way:

auto str = make_unique(\"my string\");
auto lambda = [ capturedStr = std::move(str)          


        
相关标签:
3条回答
  • 2021-02-01 02:22
    auto lambda = [ capturedStr = std::move(str) ] {
       cout << *capturedStr.get() << endl;
       auto str2 = std::move(capturedStr); // <--- Not working, why?
    };
    

    To give more detail the compiler is effectively making this transformation:

    class NameUpToCompiler
    {
        unique_ptr<string> capturedStr;  // initialized from move assignment in lambda capture expression
    
        void operator()() const
        {
            cout << *capturedStr.get() << endl;
            auto str2 = std::move(capturedStr);  // move will alter member 'captureStr' but can't because of const member function.
        }
    }
    

    The use of mutable on the lambda will remove the const from the operator() member function therefore allowing the members to be altered.

    0 讨论(0)
  • 2021-02-01 02:24

    To make the advice more explicit: add mutable: http://coliru.stacked-crooked.com/a/a19897451b82cbbb

    #include <memory>
    
    int main()
    {
        std::unique_ptr<int> pi(new int(42));
    
        auto ll = [ capturedInt = std::move(pi) ] () mutable { };
    }
    
    0 讨论(0)
  • 2021-02-01 02:44

    The operator () of a lambda is const by default, and you can't move from a const object.

    Declare it mutable if you want to modify the captured variables.

    auto lambda = [ capturedStr = std::move(str) ] () mutable {
    //                                             ^^^^^^^^^^
        cout << *capturedStr.get() << endl;
        auto str2 = std::move(capturedStr);
    };
    
    0 讨论(0)
提交回复
热议问题