मैं निम्नलिखित इनपुट कमांड के साथ Coliru में इस विषय का पता लगाया:std :: shared_ptr <T> = std :: unique_ptr <T[]> संकलन क्यों करता है, जबकि std :: shared_ptr <T[]> = std :: unique_ptr <T[]> नहीं है?
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
परीक्षण here पाया जा सकता है, लेकिन मैं नीचे दिए गए कोड को तैनात किया है। मैंने अपने उदाहरण में int
का उपयोग किया, क्योंकि यह एक मूल प्रकार है।
#include <iostream>
#include <memory>
struct Foo{
Foo() :
a_{0}, b_{1}, c_{-1}, combination_{0.5} {}
int
a_,
b_,
c_;
double
combination_;
};
int main()
{
//int
// *unManagedArray = new int[16];
std::unique_ptr<int[]>
uniqueArrayOrigin = std::make_unique<int[]>(16);
std::shared_ptr<int>
// works but needs call to new
// sharedSingleTest{unManagedArray, std::default_delete<int[]>{}};
// works, does not require call to new
sharedSingleUnique = std::make_unique<int[]>(16);
// compilation error (conversion to non-scalar type)
// sharedSingleDerived = uniqueArrayOrigin;
// std::shared_ptr<int[]>
// compilation errors
// sharedArrayTest{unManagedArray, std::default_delete<int[]>{}};
// compilation error (conversion to non-scalar type)
// sharedArrayUnique = std::make_unique<int[]>(16);
// compilation error (conversion to non-scalar type)
// sharedArrayDerived = uniqueArrayOrigin;
std::shared_ptr<Foo>
// works: specified overload of operator= for shared_ptr
nonArrayTest = std::make_unique<Foo>();
std::cout << "done!\n";
}
मैं इतना जवाब के लिए, लेकिन केवल ऊपर referencesstd::shared_ptr
एक विशेषज्ञता नहीं होने के कार्यान्वयन में बदल गया पर चारों ओर देखा है, और कहा कि यह काफी हद तक था क्योंकि कोई भी एक उचित देने के लिए परेशान विषय पर मानकों समिति के प्रस्ताव।
मैं उत्सुक,, सब के बाद कर रहा हूँ क्योंकि मैं operator=
, std::shared_ptr<T[]>.operator=(std::unique_ptr<T[], Deleter>&&)
cppreference पर के 4 अधिभार व्याख्या इंगित करने के लिए इस तरह के वाक्य रचना है कि legal-- T[]
और T[]
std::shared_ptr
के लिए सरणी प्रकार के लिए विशेषज्ञता के राज्य की परवाह किए बिना एक ही प्रकार के हैं जाएगा ।
इसके अलावा, यह वाक्यविन्यास केवल std::make_unique<T[]>
के उत्पाद पर काम करता प्रतीत होता है, और एक अद्वितीय सूचक वस्तु नहीं है, जो विषय की मेरी समझ के खिलाफ जाता है - कॉल को प्रभावी रूप से समान नहीं होना चाहिए, हालांकि कोई मौजूदा रूप से चलता है ऑब्जेक्ट, और दूसरा, ठीक है, एक ऑब्जेक्ट चलाता है जिसे अभी बनाया गया है? मैं उम्मीद करता हूं कि पहले मामले में फ़ंक्शन कॉल के बाद उनके बीच एकमात्र अंतर अमान्य std::unique_ptr<T[]>
होगा।
एक तरफ ध्यान दें के रूप में, मुझे लगता है कि के बाद से वहाँ एक shared_ptr
में एक गतिशील रूप से आवंटित सरणी कि new
के उपयोग की आवश्यकता नहीं है के निर्माण का एक तरीका है, मैं इसे मेसियर और अपवाद-असुरक्षित कॉल करने के लिए new T[N]
करना पसंद करते हैं चाहिए ?
tl; डॉ:
operator=
बिल्कुलstd::shared_ptr<T[]>
औरstd::unique_ptr<T[]>
के बीच काम नहीं करता है, हालांकि मैं यह काम करने की उम्मीद होगी। क्यूं कर?- यदि कुछ भी है, तो मैं अद्वितीय और साझा पॉइंटर्स के बीच संकलन त्रुटियों का स्रोत होने के लिए
T[]
सेT
पर प्रकार रूपांतरण की अपेक्षा करता हूं। यह क्यों काम करता है? operator=
std::shared_ptr<T>
औरstd::make_unique<T[]>
के बीच काम करता है लेकिनstd::unique_ptr<T[]>
नहीं। क्यूं कर?- क्या मैं उन मामलों में मानने के लिए सही हूं जिनके लिए गतिशील रूप से आवंटित, साझा सरणी की आवश्यकता होती है, लेकिन जहां मैं बूस्ट या वेक्टर (नीचे कारणों) का उपयोग नहीं करना चाहता हूं, मुझे
operator= std::make_unique<T[]>(N)
पर कॉल करना चाहिए?
मैं क्यों उपयोग नहीं कर रहा हूं?
- बूस्ट: मेरी कंपनी में अभी तक उपयोग की अनुमति नहीं है, और मैं नहीं जानता कि जब या अगर मैं इसे उपयोग करने की स्वीकृति मिल जाएगा।
- Arrays: मुझे रनटाइम पर इस सरणी का आकार निर्धारित करना होगा।
- वेक्टर: मैं रीयल-टाइम सिग्नल प्रोसेसिंग सिस्टम पर काम कर रहा हूं, और अतिरिक्त पॉइंटर अव्यवस्था से बचना पसंद करूंगा। मैं अपने हेडर फाइलों में बाहरी पुस्तकालयों से बचने का भी प्रयास कर रहा था (यह उपप्रणाली को पढ़ने और लिखने के बीच संचार के लिए था) हालांकि, अगर मैं महत्वपूर्ण (समयपूर्व अनुकूलन ...) और बुलेट काटने का अंततः इसे बाद में अनुकूलित करना चुना। सवाल अभी भी बनी हुई है।
वर्तमान में, 'std :: shared_ptr' सरणी का समर्थन नहीं करता है। –
स्पष्टीकरण के लिए: यह केवल इतना मामला नहीं है कि सरणी प्रकारों के लिए विशेषज्ञता मौजूद नहीं है, लेकिन 'std :: shared_ptr' सक्रिय रूप से सरणी का समर्थन नहीं करता है? मैंने माना था कि एक विशेषज्ञता की कमी का मतलब है कि यह सरणी प्रकारों पर काम करता था जैसे कि वे किसी अन्य प्रकार के थे। – jaggedSpire