2011-12-19 26 views
12

निम्न कोड को संकलित करता बजना 3.0 के साथ/libC++:std :: make_shared, std :: unique_ptr और चाल कंस्ट्रक्टर्स

#include <memory> 

class Foo 
{ 
public: 
    Foo() 
     : mem_(new int(10)) 
    { 
    } 
    std::unique_ptr<int> mem_; 
}; 

int main() 
{ 
    auto foo = std::make_shared<Foo>(); 
    return 0; 
} 

लेकिन यह एक (std::string पैरामीटर जोड़ा) नहीं करता है:

#include <memory> 
#include <string> 

class Foo 
{ 
public: 
    Foo(const std::string& s) 
     : mem_(new int(10)) 
    { 
    } 
    std::unique_ptr<int> mem_; 
}; 

int main() 
{ 
    auto foo = std::make_shared<Foo>("aaa"); 
    return 0; 
} 

क्लैंग एक हटाए गए कन्स्ट्रक्टर के उपयोग के बारे में शिकायत करता है। मेरे लिए, इसका कोई मतलब नहीं है, क्योंकि std::make_shared को Foo इंस्टेंस की प्रतिलिपि नहीं माना जाता है, केवल एक चीज जो std::unique_ptr के (हटाए गए) प्रतिलिपि निर्माता को कॉल ट्रिगर करेगी।

लेकिन देखो और जैसे ही मैं एक चालक कन्स्ट्रक्टर को स्पष्ट रूप से परिभाषित करता हूं, यह संकलित करता है।

#include <memory> 
#include <string> 

class Foo 
{ 
public: 
    Foo(const std::string& s) 
     : mem_(new int(10)) 
    { 
    } 
    Foo(Foo&& other) 
     : mem_(std::move(other.mem_)) 
    { 
    } 
    std::unique_ptr<int> mem_; 
}; 

int main() 
{ 
    auto foo = std::make_shared<Foo>("aaa"); 
    return 0; 
} 

अब, सवाल:

  1. क्यों यह पहले उदाहरण में संकलित करता है, लेकिन दूसरी नहीं?
  2. std::make_shared इसे बनाते समय वस्तु को प्रतिलिपि/स्थानांतरित कर सकते हैं?
  3. एक चालक कन्स्ट्रक्टर जोड़ने से समस्या ठीक क्यों होती है? मुझे याद नहीं है कि गैर-डिफ़ॉल्ट कन्स्ट्रक्टर जोड़ने से एक अंतर्निहित चाल कन्स्ट्रक्टर को दबाया जाना चाहिए।

संपादित करें: की जांच की गई और सभी उदाहरण जीसीसी 4.5.1 (ideone.com के माध्यम से), मुझे लगता है कि यह एक बजना/libC++ बग की बात है के साथ ठीक संकलित करने के लिए दिखाई देते हैं, लेकिन सवाल 2 और 3 अभी भी खड़े हो जाओ, प्लस मैं जानना चाहता हूं कि कौन सा कंपाइलर अधिक "सही" है।

+1

मुझे नहीं लगता कि कभी एक अंतर्निहित कदम प्रदान की निर्माता है –

+0

@parapura राजकुमार (1) unique_ptr को हटाने इसे दूर (यहां तक ​​कि गैर-डिफ़ॉल्ट करते जाते हैं सीटीओआर), (2) निहित चाल कन्स्ट्रक्टर अभी भी नवीनतम शब्द के अनुसार परिभाषित किया गया है: http: //mmocny.wordpress।कॉम/2010/12/09/implicit-move-wont-go/ –

+0

@parapurarajkumar: वास्तव में, मुझे उन चर्चाओं को पढ़ने की याद आती है जहां निहित चालक रचनाकार एक बुरी चीज थीं, और मानक से हटा दी जानी चाहिए। हालांकि, मैं कहानी के अंत को नहीं जानता। –

उत्तर

20

यह पहले उदाहरण में क्यों संकलित करता है लेकिन दूसरा नहीं?

यह एक libC++ बग है। मैं अब इसके लिए एक फिक्स पर काम कर रहा हूं ...

क्या std :: make_shared प्रतिलिपि बनाकर ऑब्जेक्ट को स्थानांतरित कर सकता है?

नहीं, मुझे विश्वास नहीं है कि यह कर सकता है।

एक चालक कन्स्ट्रक्टर जोड़ने से समस्या ठीक क्यों होती है? मुझे याद नहीं है कि गैर-डिफ़ॉल्ट कन्स्ट्रक्टर को जोड़ने से एक अंतर्निहित चाल कन्स्ट्रक्टर को दबाया जाना चाहिए।

क्लैंग के संस्करण में आप उपयोग कर रहे हैं, निहित चाल रचनाकार अभी तक लागू नहीं किए गए हैं।

अद्यतन

फिक्स्ड: http://llvm.org/bugs/show_bug.cgi?id=11616

+5

वाह! एक घंटा चारों ओर मुड़ें! तो अगर हमें क्लैंग/libC++ में अन्य बग मिलती हैं तो हम उन्हें तुरंत उन्हें ठीक करने में शर्मिंदा करने के लिए स्टैक ओवरफ्लो पर पोस्ट कर सकते हैं? –

+3

@deft_code: मुझे लगता है कि हावर्ड इसके बिना शर्मिंदा किए बग को ठीक करने के लिए पर्याप्त है। ; -] – ildjarn

+3

@deft_code: यह एक प्रभाव तकनीक प्रतीत होता है। ;-) –

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