2015-05-29 6 views
16

मैं लैम्ब्डा के अंदर एक कच्चा सूचक पास करना चाहता हूं, लेकिन अगर मैं लैम्ब्डा नहीं बुलाता हूं, तो मैं इसे लीक नहीं करना चाहता हूं। यह इस तरह दिखता है:मैं C++ 14 में lambda के अंदर std :: unique_ptr क्यों नहीं चला सकता?

void Clean(std::unique_ptr<int>&& list); 

void f(int* list) { 
    thread_pool.Push([list = std::unique_ptr<int>(list) ] { 
    Clean(std::move(list)); // <-- here is an error. 
    }); 
} 

मैं बजना 3.7.0 में कोई त्रुटि मिलती है:

error: binding of reference to type 'unique_ptr<[2 * ...]>' to a value of type 'unique_ptr<[2 * ...]>' drops qualifiers

लेकिन मैं पहले स्थान पर किसी भी क्वालिफायर नहीं दिख रहा है, विशेष रूप से गिरा दिया।

इसके अलावा, मुझे मेलिंग सूची पर समान report मिला, लेकिन उत्तर के बिना।


मैं कैसे तो यह संकलित और शब्दों को आशा के अनुरूप काम करता है हो जाता है, मेरे कोड को संशोधित करना चाहिए?

+0

क्या 'साफ()' है? जब मैं क्लैंग पर पुनर्विचार करने की कोशिश करता हूं, मान लीजिए कि 'क्लीन() 'मूल्य से' unique_ptr' लेता है, तो मुझे "त्रुटि मिलती है:' std :: unique_ptr 'के हटाए गए कन्स्ट्रक्टर को कॉल करें, जो अधिक समझ में आता है। – Barry

+0

@ बैरी I हेवन मूल के बाद किसी भी अन्य त्रुटि की उम्मीद नहीं है। अभी मैं सभी को ठीक करने की कोशिश कर रहा हूं और प्रश्न में कोड अपडेट कर रहा हूं, ताकि मूल त्रुटि केवल एक ही हो। –

उत्तर

24

आप आंतरिक लैम्ब्डा mutable बनाने की जरूरत है:

[this](Pointer* list) { 
    thread_pool.Push([this, list = std::unique_ptr<int>(list) ]() mutable { 
                   ^^^^^^^^^ 
    Clean(std::move(list)); 
    }); 
}; 

operator() lambdas पर const डिफ़ॉल्ट रूप से है, तो आप उस कॉल में अपने सदस्यों को संशोधित नहीं कर सकते हैं। इस प्रकार, आंतरिक list व्यवहार करता है जैसे कि यह const std::unique_ptr<int> था। जब आप move कास्ट करते हैं, तो इसे const std::unique_ptr<int>&& में परिवर्तित कर दिया जाता है। यही कारण है कि आप क्वालीफायर छोड़ने के बारे में संकलन त्रुटि प्राप्त कर रहे हैं: आप कॉन्स एक गैर-कॉन्स्ट रावल संदर्भ के रावल्यू संदर्भ को परिवर्तित करने का प्रयास कर रहे हैं। त्रुटि उतनी उपयोगी नहीं हो सकती है जितनी हो सकती है, लेकिन यह सब नीचे उबलती है: आप moveconst unique_ptr नहीं कर सकते हैं।

mutable फिक्स करता है कि - operator() अब const नहीं है, इसलिए समस्या अब लागू नहीं होती है।

नोट: यदि आपके Clean() एक unique_ptr<int> बजाय ले लिया एक unique_ptr<int>&&, जो और अधिक समझ में आता है की (के रूप में यह एक और अधिक स्पष्ट, नियतात्मक सिंक है), तो त्रुटि हो गया होता एक बहुत अधिक स्पष्ट:

error: call to deleted constructor of `std::unique_ptr<int>` 
note: 'unique_ptr' has been explicitly marked deleted here 

    unique_ptr(const unique_ptr&) = delete 
    ^
+2

ओटीओएच, त्रुटि संदेश अत्याचारी है। –

+0

यह उल्लेख करना उपयोगी होगा कि लैम्ब्डा स्वयं ही एकमात्र वस्तु बन जाता है, इसलिए मुझे इसे स्पष्ट रूप से 'thread_pool.Push()' –

+0

@ abyss.7 के अंदर स्थानांतरित करने की आवश्यकता है। मुझे नहीं पता कि 'thread_pool.Push()' – Barry

संबंधित मुद्दे