2013-07-28 9 views
5

साथ init हो रही नहीं है जब मैं deleter के साथ एक unique_ptr बनाने के लिए, यह काम करता है:unique_ptr डिफ़ॉल्ट Deleter

std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr(new Animal<Cat>, [](Animal<Cat> *ls) { 
    delete ls; 
}); 

लेकिन, इस कोड को त्रुटि फेंक है:

std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr; 
ptr = std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)>(new Animal<Cat>, [](Animal<Cat> *ls) { 
    delete ls; 
}); 

त्रुटि:

/usr/bin/../lib/c++/v1/memory:2561:13: error: static_assert failed "unique_ptr constructed with null function pointer deleter" 
       static_assert(!is_pointer<deleter_type>::value, 
       ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
note: in instantiation of member function 'std::__1::unique_ptr<Animal<Cat>, void (*)(Animal<Cat> *)>::unique_ptr' requested here 
      std::unique_ptr<Animal<Cat>, void(*)(Animal<Cat>*)> ptr; 
                   ^

यह मेरा कंपाइलर संस्करण है:

Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn) 
Target: x86_64-apple-darwin12.4.0 
Thread model: posix 

पशु और बिल्ली कक्षाएं छोटी हैं। This is the entire code

उत्तर

10

यह स्पष्ट रूप से डिफ़ॉल्ट रूप से संभव नहीं है-unique_ptr को डिलीटर के लिए पॉइंटर प्रकार के साथ बनाना।

unique_ptr<int, void(*)(int*)> ptr{nullptr,[](int*p){delete p;}}; 
// ... 
ptr.reset(new int(42)); 
:

constexpr unique_ptr() noexcept;

4 Remarks: If this constructor is instantiated with a pointer type or reference type for the template argument D [the deleter type], the program is ill-formed.

कुछ आप क्या चाहते हैं कि मानक के अनुरूप है के समान: unique_ptr कंस्ट्रक्टर्स में §20.7.1.2.1 [unique.ptr.single.ctor] जो कहते हैं, अन्य बातों के अलावा विस्तृत कर रहे हैं

10

केसी के उत्तर को पढ़ने के बाद, मैंने अपना कोड बदलकर काम करने के लिए लैम्ब्डा के बजाय अच्छे पुराने फ़ंक्चरर्स का उपयोग करने के लिए बदल दिया।

struct Deleter { 
    void operator()(Animal<Cat>* ls) { 
     delete ls; 
    } 
}; 

int main() { 
    std::unique_ptr<Animal<Cat>, Deleter> ptr; 
    ptr = std::unique_ptr<Animal<Cat>, Deleter>(new Animal<Cat>); 
    return 0; 
} 
+1

इस 'unique_ptr' व्यवहार के लिए तर्क संकलन समय है कि एक नल पॉइंटर करने वाली समारोह एक अच्छा Deleter नहीं है पर आपको सूचित करने की कोशिश करने के लिए है:

यह मेरा समाधान है। आप स्पष्ट रूप से एक nullptr deleter में भेजकर इस व्यवहार को ओवरराइड कर सकते हैं। लेकिन इसके बजाय आपने जो समाधान चुना है वह बेहतर इमो है। –

+0

@ हावर्ड हिन्नेंट क्या यह रनटाइम पर नलप्टर की जांच करेगा या क्या वह उस समारोह को कॉल करने का प्रयास करेगा? – user877329

+0

@ user877329: यदि '~ unique_ptr()' या 'reset()' कहा जाता है और 'get_deleter() (get()) 'अच्छी तरह से गठित नहीं होता है, तो आपको अपरिभाषित व्यवहार मिलता है। –