एसटीएल या क्यूटी कंटेनर?


185

पेशेवरों और क्यूटी कंटेनर (का उपयोग करने का विपक्ष क्या हैं QMap, QVectorउनके एसटीएल बराबर से अधिक, आदि)?

मैं क्यूटी पसंद करने का एक कारण देख सकता हूं:

  • क्यूटी कंटेनरों को क्यूटी के अन्य हिस्सों के साथ पारित किया जा सकता है। उदाहरण के लिए, उनका उपयोग पॉप्युलेट करने के लिए किया जा सकता है QVariantऔर फिर ए QSettings(कुछ सीमा के साथ हालांकि, केवल QListऔर QMap/ QHashजिनकी कुंजी स्ट्रिंग हैं स्वीकार किए जाते हैं)।

क्या कोई और है?

संपादित करें : मान लिया गया कि एप्लिकेशन पहले ही Qt पर निर्भर है।

जवाबों:


135

मैंने std::(w)stringएसटीएल कंटेनरों का उपयोग करके और विशेष रूप से / क्यूटी समकक्षों से / में परिवर्तित करके शुरू किया था , लेकिन मैंने पहले ही स्विच कर दिया है QStringऔर मुझे पता चलता है कि मैं क्यूटी के कंटेनरों का अधिक से अधिक उपयोग कर रहा हूं।

जब यह स्ट्रिंग्स की बात आती है, तो QStringइसकी तुलना में बहुत अधिक पूर्ण कार्यक्षमता प्रदान करता है std::basic_stringऔर यह पूरी तरह से यूनिकोड जागरूक है। यह एक कुशल गाय कार्यान्वयन भी प्रदान करता है , जिसे मैं बहुत अधिक भरोसा करने के लिए आया हूं।

क्यूटी के कंटेनर:

  • के रूप में एक ही गाय के कार्यान्वयन की पेशकश QString, जो अत्यंत उपयोगी है जब यह क्यूटी के foreachमैक्रो (जो एक कॉपी करता है) और मेटा-प्रकार या सिग्नल और स्लॉट का उपयोग करते समय आता है ।
  • एसटीएल शैली पुनरावृत्तियों या जावा शैली पुनरावृत्तियों का उपयोग कर सकते हैं
  • के साथ सुव्यवस्थित हैं QDataStream
  • Qt के एपीआई में बड़े पैमाने पर उपयोग किया जाता है
  • ऑपरेटिंग सिस्टम में एक स्थिर कार्यान्वयन है। एक STL कार्यान्वयन को C ++ मानक का पालन करना चाहिए, लेकिन अन्यथा ऐसा करने के लिए स्वतंत्र है (जैसा कि std::stringगाय का विवाद देखें )। कुछ एसटीएल कार्यान्वयन विशेष रूप से खराब हैं।
  • जब तक आप TR1 का उपयोग नहीं करते हैं, हैश उपलब्ध कराते हैं

क्यूटीएल का एसटीएल से एक अलग दर्शन है, जिसे जे। ब्लैंचेट द्वारा संक्षेप में प्रस्तुत किया गया है: "जहां एसटीएल के कंटेनरों को कच्ची गति के लिए अनुकूलित किया गया है, क्यूटी के कंटेनर वर्गों को सुविधा, न्यूनतम स्मृति उपयोग और न्यूनतम कोड विस्तार प्रदान करने के लिए सावधानीपूर्वक डिजाइन किया गया है।"
उपरोक्त लिंक क्यूटीएल के कार्यान्वयन के बारे में अधिक विवरण प्रदान करता है और क्या अनुकूलन का उपयोग किया जाता है।


12
नए मानक में c ++ 0x गाय तालिका से बहुत अधिक है।

16
पुनः: "ध्यान से प्रदान करने के लिए डिज़ाइन किया गया [...] न्यूनतम स्मृति उपयोग"। आपको मार्केटिंग पर विश्वास नहीं करना चाहिए। QList<double>मेमोरी के लिए 32-बिट आर्किटेक्चर पर प्रोफ़ाइल अपने आप को देखने के लिए उपयोग करें।
मार्क मुत्ज़ - mmutz

11
"यह भी एक कुशल गाय कार्यान्वयन प्रदान करता है": गाय यह सब कुशल नहीं है जब यह multithreaded अनुप्रयोगों के लिए आता है ...
ग्रिजली

5
@ MarcMutz-mmutz के QVectorबजाय प्रोफ़ाइल करने का प्रयास करें QList। बहुत क्यूटी स्पष्टीकरण हैं, कि क्यूएलस्ट को ऑब्जेक्ट्स पर पॉइंटर्स को स्टोर करने के लिए डिज़ाइन किया गया है। तो इस आइटम के लिए गतिशील और पॉइंटर बनाए गए प्रत्येक डबल आइटम को संग्रहीत किया जाता है QList। QList को वेक्टर और लिंक्ड सूची के बीच "मध्य" कंटेनर के रूप में डिज़ाइन किया गया है। यह मेमोरी / प्रदर्शन महत्वपूर्ण मामलों के लिए डिज़ाइन नहीं किया गया है।
दिमित्री सोजोनोव

2
@ user1095108 इसमें कुछ भी गलत नहीं है। स्टाल का उपयोग करें। हम में से कुछ लोग जल्दी से सही कोड लिखना पसंद करते हैं। इसमें कुछ भी गलत नहीं है।
वेबर 2

178

इस सवाल का जवाब देना मुश्किल है। यह वास्तव में एक दार्शनिक / व्यक्तिपरक तर्क को उबाल सकता है।

ऐसा कहे जाने के बाद...

मैं नियम की सिफारिश करता हूं "जब रोम में ... रोम के रूप में करो"

जिसका अर्थ है कि यदि आप Qt भूमि में हैं, तो Qt'ians के रूप में कोड। यह सिर्फ पठनीयता / स्थिरता की चिंताओं के लिए नहीं है। विचार करें कि क्या होता है यदि आप सब कुछ एक stl कंटेनर में संग्रहीत करते हैं, तो आपको उस डेटा को Qt फ़ंक्शन पर पास करना होगा। क्या आप वास्तव में कोड का एक गुच्छा प्रबंधित करना चाहते हैं जो क्यूटी कंटेनरों में चीजों को कॉपी / आउट करता है। आपका कोड पहले से ही क्यूटी पर बहुत अधिक निर्भर है, इसलिए यह पसंद नहीं है कि आप स्टेल कंटेनरों का उपयोग करके इसे और अधिक "मानक" बना रहे हैं। और एक कंटेनर का क्या मतलब है अगर हर बार आप इसे किसी भी उपयोगी चीज के लिए उपयोग करना चाहते हैं, तो आपको इसे इसी क्यूटी कंटेनर में कॉपी करना होगा?


1
+1, आप पूरी तरह से सही हैं, यही मैंने अपने प्रश्न में समझाने की कोशिश की ("मैं क्यूटी को पसंद करने का एक कारण देख सकता हूं") इसलिए मैंने इसे थोड़ा संपादित किया। साभार
जुलिएन-एल

बिलकुल ठीक कहा। यदि आप क्यूटी कर रहे हैं, तो क्यूटी सामान का उपयोग करें! अनुचर के लिए "डब्ल्यूटीएफ" क्षण की कल्पना करें जब वह एक क्यूटी एप्लिकेशन खोलता है और क्यूटी और एसटीएल को परस्पर विनिमय करता है। यह अंत में एक (अनावश्यक) बुरा सपना हो सकता है।
शाम

5
@ ItPete STL मानक का हिस्सा है; क्यूटी नहीं है। कोई भी कोड जो मानक का उपयोग करता है, उसे कभी भी "डब्ल्यूटीएफ" क्षण को ट्रिगर नहीं करना चाहिए।
ऐलिस

5
रोमन ने अपने बंदियों को कोलोसियम में डाल दिया और फिर शेरों के साथ उनका शिकार किया। यदि आप बेहतर जानते हैं, तो स्थानीय आदतों का पालन न करें। कि क्यूटी में यह उतना ही सच है जितना कि रोमन साम्राज्य में मॉडर्न मैन के लिए ...
मार्क मुत्ज़ - mmutz

1
@mmutz आप कहते हैं कि जैसे यह एक बुरी बात है, मैं उस कोलोसियम में पाया गया कुछ कोड डालना चाहता हूं और शो देखना
चाहता हूं

64

क्यूटी कंटेनर एसटीएल वालों की तुलना में अधिक सीमित हैं। एसटीएल वाले कहां से बेहतर हैं, इसके कुछ उदाहरण (इन सभी को मैंने अतीत में देखा है):

  • STL मानकीकृत है, हर Qt संस्करण के साथ नहीं बदलता है (Qt 2 में QList(सूचक-आधारित) और QValueList(मूल्य-आधारित) था, Qt 3 के पास था QPtrListऔर QValueListQt 4 के पास अब है QList, और यह कुछ भी ऐसा नहीं है QPtrList या QValueList )।
    (। यानी अगर आप क्यूटी कंटेनरों का इस्तेमाल खत्म, एसटीएल संगत एपीआई सबसेट का उपयोग push_back(), नहीं append(); front(), नहीं first(), ...) एक बार फिर पोर्टिंग क्यूटी 5. आ दोनों Qt2-> 3 और Qt3- में से बचने के लिए 4> संक्रमण, क्यूटी कंटेनरों में परिवर्तन उन लोगों में से थे जिन्हें सबसे अधिक कोड मंथन की आवश्यकता थी।
  • एसटीएल द्विदिश कंटेनरों में सभी rbegin()/ / हैं rend(), जो आगे की ओर पुनरावृत्ति को सममित बनाते हैं। सभी क्यूटी कंटेनरों में उन्हें (साहचर्य वाले नहीं होते हैं), इसलिए रिवर्स पुनरावृत्ति अनावश्यक रूप से जटिल है।
  • एसटीएल कंटेनरों की रेंज insert()अलग-अलग, लेकिन संगत, पुनरावृत्त प्रकारों से होती है, जिससे std::copy()बहुत कम बार जरूरत होती है।
  • एसटीएल कंटेनरों में एक Allocatorटेम्प्लेट तर्क होता है, जो कस्टम मेमोरी प्रबंधन को तुच्छ (टाइप किए गए आवश्यक), क्यूटी ( QLineEditआवश्यक के कांटा ) की तुलना में बनाता है s/QString/secqstring/EDIT 20171220 : यह C ++ 11 और C ++ 17, cf के बाद एलोकेटर डिजाइन में अग्रिमों की Qt कटौती करता है। उदाहरण के लिए जॉन लैकोस की बात ( भाग 2 )।
  • के बराबर कोई क्यूटी नहीं है std::deque
  • std::listहै splice()। जब भी मैं खुद को इस्तेमाल करते हुए पाता हूं std::list, इसकी जरूरत मुझे है splice()
  • std::stackstd::queueठीक से , उनके अंतर्निहित कंटेनर को समुचित रूप से संयोजित करें, और इसे विरासत में न लें, जैसा कि QStack, QQueueकरते हैं।
  • QSetजैसा है std::unordered_set, वैसा नहीं है std::set
  • QListएक अजीब है

उपरोक्त में से कई को क्यूटी में काफी आसानी से हल किया जा सकता है , लेकिन क्यूटी में कंटेनर लाइब्रेरी इस समय विकास फोकस की कमी का अनुभव करता है।

EDIT 20150106 : Qt 5 कंटेनर कक्षाओं में C ++ 11-support लाने की कोशिश में कुछ समय बिताने के बाद, मैंने फैसला किया है कि यह काम के लायक नहीं है। यदि आप उस कार्य को देखते हैं जो C ++ मानक पुस्तकालय कार्यान्वयन में डाला जा रहा है, तो यह बिल्कुल स्पष्ट है कि क्यूटी कक्षाएं कभी नहीं पकड़ेगी। हमने Qt 5.4 जारी कर दिया है औरQVector अभी भीemplace_back() वास्तविकताओंपर तत्वों को स्थानांतरित नहीं करता है,यानहीं हैया नहीं-push_back()... हमने हाल ही में एकQOptionalवर्ग टेम्पलेट कोअस्वीकार कर दिया है,std::optionalइसके बजायप्रतीक्षा कर रहा है। इसी तरह के लिएstd::unique_ptr। मुझे उम्मीद है कि ट्रेंड जारी है।


3
हुह। मैं इस धारणा के अधीन QList था कि इसके समकक्ष था std::deque। स्पष्ट रूप से, मुझे केवल दस्तावेज स्किम्ड नहीं करना चाहिए था।
डेनिस ज़िकफ़ोज़

QVectorपड़ा है crbeginक्यूटी 5.6 के बाद से और दोस्तों
बार्ट Louwers

@ एलेक्स: सही है, मैंने आसान लोगों को जोड़ा, लेकिन सभी क्यूटी कंटेनरों में उनके पास नहीं है, फिर भी (क्योंकि आप std::reverse_iteratorटूटे हुए QHash/ QMapपुनरावृत्तियों पर उपयोग नहीं करते हैं , जो कि जब छूट गए, तो mapped_typeबदले में value_type)। कुछ भी तय नहीं किया जा सकता है, लेकिन मेरे EDIT को 2015 से देख सकते हैं
मार्क मुत्ज़ - mmutz

@ MarcMutz-mmutz स्पष्ट करने के लिए धन्यवाद।
बार्ट लूवर

इस तथ्य को सूची में जोड़ने के लायक हो सकता है कि उदाहरण के QVectorलिए intइसके सूचकांक के रूप में उपयोग किया जाता है, इस प्रकार 31-बिट आकार (64-बिट सिस्टम पर भी) को सीमित करता है । इसके अलावा, यह INT_MAX1 बाइट से बड़े आकार के तत्वों को स्टोर भी नहीं कर सकता है । उदाहरण के लिए, x86_64 लिनक्स gcc पर .size()मेरा सबसे बड़ा QVector<float>536870907 तत्व (2²⁹-5) था, जबकि std::vector<float>सफलतापूर्वक 4294967295 तत्वों को आवंटित किया गया (2 have-1; इसके लिए RAM की कमी के कारण अधिक प्रयास नहीं किया गया था (यह आकार पहले से ही 16 GiB लेता है) )।
रुस्लान

31

आइए इन दावों को वास्तविक औसत दर्जे की घटनाओं में तोड़ दें:

  • हल्का: क्यूटी कंटेनर एसटीएल कंटेनरों की तुलना में कम मेमोरी का उपयोग करते हैं
  • सुरक्षित: क्यूटी कंटेनरों का अनुचित तरीके से उपयोग करने का अवसर कम है
  • आसान: क्यूटी कंटेनर एक बौद्धिक बोझ कम प्रस्तुत करते हैं

आसान

इस संदर्भ में किया गया दावा यह है कि जावा शैली की पुनरावृत्ति एसटीएल शैली की तुलना में किसी तरह "आसान" है, और इसलिए क्यूटी को इस अतिरिक्त इंटरफ़ेस के कारण उपयोग करना आसान है।

जावा शैली:

QListIterator<QString> i(list);
while (i.hasNext())
    qDebug() << i.next();

एसटीएल शैली:

QList<QString>::iterator i;
for (i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

जावा इटैलर स्टाइल में थोड़ा छोटा और क्लीनर होने का लाभ है। समस्या यह है, यह वास्तव में अब एसटीएल शैली नहीं है।

सी ++ 11 एसटीएल स्टाइल

for( auto i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

या

C ++ 11 फ़ॉरच स्टाइल

for (QString i : list)
    qDebug << i;

जो इतना सरल है कि कभी भी किसी और चीज का उपयोग करने का कोई कारण नहीं है (जब तक कि आप C ++ 11 का समर्थन नहीं करते)।

मेरा पसंदीदा, हालांकि, है:

BOOST_FOREACH(QString i, list)
{
    qDebug << i;
}

इसलिए, जैसा कि हम देख सकते हैं, यह इंटरफ़ेस हमें अतिरिक्त इंटरफ़ेस के अलावा कुछ नहीं देता है, पहले से ही चिकना, सुव्यवस्थित और आधुनिक इंटरफ़ेस के शीर्ष पर। पहले से ही स्थिर और प्रयोग करने योग्य इंटरफ़ेस के शीर्ष पर अमूर्तता का अनावश्यक स्तर जोड़ना? "आसान" के मेरे विचार नहीं।

इसके अलावा, क्यूटी फॉरचेक और जावा इंटरफेस ओवरहेड जोड़ते हैं; वे संरचना की नकल करते हैं, और अप्रत्यक्ष स्तर का एक अनावश्यक स्तर प्रदान करते हैं। यह बहुत ज्यादा नहीं लग सकता है, लेकिन एक बहुत अधिक सरल इंटरफ़ेस प्रदान करने के लिए ओवरहेड की एक परत क्यों जोड़ें? जावा में यह इंटरफ़ेस है क्योंकि जावा में ऑपरेटर ओवरलोडिंग नहीं है; सी ++ करता है।

सुरक्षित

Qt जो औचित्य देता है वह निहित बंटवारे की समस्या है, जो न तो निहित है और न ही समस्या है। हालाँकि इसमें साझाकरण शामिल है।

QVector<int> a, b;
a.resize(100000); // make a big vector filled with 0.

QVector<int>::iterator i = a.begin();
// WRONG way of using the iterator i:
b = a;
/*
Now we should be careful with iterator i since it will point to shared data
If we do *i = 4 then we would change the shared instance (both vectors)
The behavior differs from STL containers. Avoid doing such things in Qt.
*/

पहला, यह निहित नहीं है; आप स्पष्ट रूप से एक वेक्टर को दूसरे को सौंप रहे हैं। STL iterator विनिर्देश स्पष्ट रूप से इंगित करता है कि पुनरावृत्त कंटेनर के हैं, इसलिए हमने स्पष्ट रूप से b और a के बीच एक साझा कंटेनर पेश किया है। दूसरा, यह कोई समस्या नहीं है; जब तक पुनरावृत्ति विनिर्देश के सभी नियमों का पालन किया जाता है, तब तक कुछ भी गलत नहीं होगा। केवल समय कुछ गलत हो जाता है:

b.clear(); // Now the iterator i is completely invalid.

Qt इसे निर्दिष्ट करता है जैसे कि इसका मतलब कुछ है, जैसे कि इस परिदृश्य से कोई समस्या उत्पन्न होती है। यह नहीं है पुनरावृत्त को अमान्य कर दिया गया है, और कुछ भी ऐसा है जो कई अलग-अलग क्षेत्रों से पहुँचा जा सकता है, यह सिर्फ यह है कि यह कैसे काम करता है। वास्तव में, यह क्यूटी में जावा शैली के पुनरावृत्तियों के साथ आसानी से घटित होगा, इसके लिए अंतर्निहित साझाकरण पर बहुत अधिक निर्भरता है, जो कि यहां दस्तावेज के रूप में एक एंटीपैटर्न है , और कई अन्य क्षेत्रों में । यह इस "अनुकूलन" के लिए विशेष रूप से अजीब लगता है कि इसे मल्टीथ्रेडिंग की ओर अधिक से अधिक बढ़ने की रूपरेखा में उपयोग में लाया जाना चाहिए, लेकिन यह आपके लिए विपणन है।

लाइटर

यह थोड़ा पेचीदा मामला है। कॉपी-ऑन-राइट और इंप्लिक्ट शेयरिंग और ग्रोथ स्ट्रैटिजिज का उपयोग वास्तव में इस बात की गारंटी देना बहुत मुश्किल हो जाता है कि किसी भी समय आपके कंटेनर में कितनी मेमोरी होगी। यह एसटीएल के विपरीत है, जो आपको मजबूत एल्गोरिथम की गारंटी देता है।

हम जानते हैं कि एक वेक्टर के लिए व्यर्थ की न्यूनतम सीमा वेक्टर की लंबाई का वर्गमूल है , लेकिन Qt में इसे लागू करने का कोई तरीका नहीं है; विभिन्न "अनुकूलन" जो वे समर्थन करते हैं, यह बहुत महत्वपूर्ण स्थान बचत सुविधा को रोक देगा। एसटीएल को इस सुविधा की आवश्यकता नहीं है (और अधिकांश दोहरीकरण वृद्धि का उपयोग करते हैं, जो अधिक बेकार है), लेकिन यह ध्यान रखना महत्वपूर्ण है कि आप कम से कम इस सुविधा को लागू कर सकते हैं, यदि आवश्यक हो।

यह दोहरी रूप से जुड़ी सूचियों के बारे में सच है, जो XOr को जोड़ने के लिए उपयोग किए गए स्थान को काफी कम कर सकता है। फिर, यह क्यूटी के साथ असंभव है, क्योंकि यह विकास और गाय की आवश्यकताओं के कारण है।

गाय वास्तव में कुछ हल्का कर सकते हैं, लेकिन इतना घुसपैठ कंटेनर, जैसे कि बूस्ट द्वारा समर्थित है , और क्यूटी ने इनका उपयोग अक्सर पहले के संस्करणों में किया था, लेकिन इनका उपयोग अब और नहीं किया जाता है क्योंकि वे उपयोग करना मुश्किल है, असुरक्षित हैं, और एक बोझ लगाते हैं प्रोग्रामर पर। गाय एक बहुत कम घुसपैठ समाधान है, लेकिन उपरोक्त कारणों के लिए बदसूरत है।

ऐसा कोई कारण नहीं है कि आप एसटीएल कंटेनरों को उसी मेमोरी लागत या क्यूटी के कंटेनरों से कम का उपयोग नहीं कर सकते हैं, वास्तव में यह जानने के अतिरिक्त लाभ के साथ कि आप किसी भी समय कितना मेमोरी बर्बाद करेंगे। कच्चे स्मृति उपयोग में दोनों की तुलना करना दुर्भाग्य से असंभव है, क्योंकि इस तरह के बेंचमार्क अलग-अलग उपयोग के मामलों में बेतहाशा भिन्न परिणाम दिखाएंगे, जो कि एसटीएल को सही करने के लिए डिज़ाइन की गई समस्या का सटीक प्रकार है।

निष्कर्ष के तौर पर

जब भी संभव हो क्यूटी कंटेनरों के उपयोग से बचें, ताकि एक प्रतिलिपि लागत लगाए बिना, और जब भी संभव हो STL प्रकार का उपयोग करें (शायद एक आवरण या नए सिंटैक्स के माध्यम से)।


4
आपके बिंदु काफी हद तक मान्य हैं, लेकिन वहाँ कुछ भ्रामक जानकारी है: Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".क्यूटी के जावा-शैली के पुनरावृत्तियों को ++ 11 पर जोड़ा नहीं गया था; वे इसे भविष्यवाणी करते हैं। वैसे भी Qt की foreach(QString elem, list)C ++ 11 की फॉर्च या BOOST_FOREACH जैसी ही आसान है और यह प्री-C ++ 11 कंपाइलर कंपाइलर के साथ काम करती है।
weberc2

@ weberc2 आप भ्रमित हैं; क्यूटी के जावा शैली के पुनरावृत्तियों को C ++ (नहीं C ++ 11) पुनरावृत्तियों के शीर्ष पर जोड़ा जाता है। यह एब्सट्रैक्शन (और एक अनावश्यक एक) की एक अतिरिक्त परत है जो इंटरफ़ेस को फुलाता है, जो आसान नहीं है। और Qt के लिए foreach BOOST_FOREACH जितना आसान नहीं है, क्योंकि यह विशेष रूप से सुरक्षित नहीं है, और इसमें समर्थन की चौड़ाई समान नहीं है (BOOST_FOREACH C ++ के किसी भी संस्करण के लिए किसी भी सीमा पर लागू हो सकता है, जहां क्यूटी में फाटक की मांग C + है +03 अनुपालन)। क्यूटी के फॉर्च्यूनर को हर कीमत पर बचना चाहिए।
ऐलिस

So, as we can see, this interface gains us nothing except an additional interface, *on top of* an already sleek, streamlined, and modern interface. Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".(जोर मेरा) आपने यह कहने के बाद यह कहा कि आपने हमें C ++ 11 और फॉर्च्यूनर के BOOST संस्करण दिखाए हैं, जिससे यह प्रतीत होता है कि Qt संस्करण उन दोनों में से एक से बना है, जो AFAICT नहीं है। मुझे यकीन है कि आप का मतलब यह नहीं है, लेकिन यह है कि यह कैसे आता है। 4. "भ्रामक जानकारी"।
वेबर 2

It's an additional layer of abstraction (and an unnecessary one) that bloats the interface, which is not easier.यह अभी भी स्पष्ट नहीं है कि आप किस चीज की तुलना कर रहे हैं। सी ++ 03 पुनरावृत्तियों? सी ++ 11 पुनरावृत्तियों? BOOST_FOREACH? ऊपर के सभी?
weberc2

1
मैं बस कह रहा हूं, आप अक्सर बहुत अस्पष्ट होते हैं कि आप किस पुनरावृत्ति विधि का उल्लेख कर रहे हैं। मेरा मानना ​​है कि आपको लगता है कि आप स्पष्ट हैं और आपकी भाषा उचित है, लेकिन यह निर्दिष्ट करने से इनकार करना अजीब लगता है। सहमत होने के लिए सहमत, मुझे लगता है।
weberc2

22

एसटीएल कंटेनर:

  • प्रदर्शन की गारंटी है
  • एसटीएल एल्गोरिदम में उपयोग किया जा सकता है जिसमें प्रदर्शन की गारंटी भी है
  • बूस्ट जैसे तृतीय-पक्ष C ++ पुस्तकालयों द्वारा लाभ उठाया जा सकता है
  • मानक हैं, और मालिकाना समाधानों की रूपरेखा तैयार करने की संभावना है
  • एल्गोरिदम और डेटा संरचनाओं के सामान्य प्रोग्रामिंग को प्रोत्साहित करें। यदि आप नए एल्गोरिदम और डेटा संरचनाएँ लिखते हैं जो एसटीएल के अनुरूप हैं तो आप इसका लाभ उठा सकते हैं जो एसटीएल पहले से ही बिना किसी लागत के प्रदान करता है।

5
एक मानक होने के अलावा उपरोक्त सभी क्यूटीएल के लिए भी सही हैं, बशर्ते कि आप एसटीएल समर्थन (डिफ़ॉल्ट) के साथ क्यूटी को संकलित करें। एसटीएल समर्थन में पुनरावृत्ति कार्य, कंटेनर टाइपडेफ़ (कॉन्स्टिटर, आदि), रूपांतरण कार्य (एसटीएल से / में) शामिल हैं।
आरपीजी

2
Qt मालिकाना नहीं है
txwikinger

2
@rpg लगभग उनमें से सभी क्यूटीएल के सच नहीं हैं; क्यूटीएल के पास कोई मजबूत प्रदर्शन की गारंटी नहीं है (जैसा कि उन्होंने आसानी से उन्हें अतीत में तोड़ दिया है), एसटीएल अनुरूप नहीं हैं (कोई उल्टा नहीं है, और इस तरह से इसे बहुत बढ़ावा नहीं दिया जा सकता है), मानक नहीं हैं (वे संस्करणों के बीच लगातार बदलते हैं), और करते हैं जेनेरिक प्रोग्रामिंग को प्रोत्साहित न करें (उनके पास आवंटन के लिए कोई टेम्पलेट तर्क नहीं हैं, उदाहरण के लिए)।
एलिस

15

क्यूटी कंटेनर कॉपी-ऑन-राइट मुहावर का उपयोग करते हैं।


2
+1, प्रदर्शन और संसाधन में एक महत्वपूर्ण लाभ हो सकता है
RedGlyph

31
या एक महत्वपूर्ण नुकसान हो सकता है। देखें gotw.ca/publications/optimizations.htm
Kaz ड्रैगन

3
परमाणु भाटा
आरपीजी

STL कंटेनरों का उपयोग करने के लिए स्वतंत्र हैं जो भी मुहावरे मौजूद हैं जब तक वे अपने प्रदर्शन की गारंटी और कल्पना को पूरा करते हैं। गाय मान्य है, C ++ 11 / C ++ 14 STL के तहत भी।
एलिस

1
@Alice गाय ज्यादातर समय एक वैध कार्यान्वयन नहीं है क्योंकि यह मानक की जटिलता को तोड़ता है और लगभग किसी भी मामले में इटेटर की वैधता की गारंटी देता है। कुछ वर्गों में से एक को गाय के साथ लागू किया जा सकता था std::basic_stringऔर इस गैर-अनुरूप बनाने के लिए मानक ने C ++ 11 के साथ कार्रवाई की।
टियागो गोम्स

9

मुख्य मुद्दों में से एक यह है कि क्यूटी के एपीआई आपको क्यूटी के कंटेनरों में डेटा प्रदान करने की उम्मीद करते हैं, इसलिए आप दोनों के बीच आगे और पीछे बदलने के बजाय बस क्यूटी कंटेनरों का उपयोग कर सकते हैं।

इसके अलावा, यदि आप पहले से ही क्यूटी कंटेनरों का उपयोग कर रहे हैं, तो यह विशेष रूप से उनका उपयोग करने के लिए थोड़ा अधिक इष्टतम हो सकता है, क्योंकि आपको एसटीएल हेडर फाइलें और एसटीएल पुस्तकालयों में संभावित लिंक शामिल नहीं करना होगा। हालाँकि, आपके टूलचेन पर निर्भर करता है, जो वैसे भी हो सकता है। विशुद्ध रूप से एक डिजाइन के नजरिए से, स्थिरता आमतौर पर एक अच्छी बात है।


1
जिस दर पर आपको एसटीएल और क्यूटी कंटेनरों के बीच "आगे और पीछे" को एक वास्तविक एप्लिकेशन में बदलना होगा जो एसटीएल का उपयोग करता है, सिवाय इसके कि क्यूटी के साथ इंटरफेसिंग को आमतौर पर बहुत कम आंका जाता है। अधिकांश समय आप कुछ एसटीडी करते हैं :: प्रस्तुति परत से (जो कि क्यूटी का उपयोग करता है) में आ रहा है और आपको कंटेनर स्विच मुफ्त में मिल रहा है। इच्छुक पार्टियां अपने लिए देखने के लिए प्रोजेक्ट्स .kde.org/projects/ kde/kdepim/repository/revisions/… पर ब्राउज़ कर सकती हैं।
मार्क मुत्ज़ -

8

यदि आप जिस डेटा के साथ काम कर रहे हैं, वह ज्यादातर क्यूटी आधारित यूआई को चलाने के लिए उपयोग किया जाता है, तो निश्चित रूप से क्यूटी कंटेनरों का उपयोग करें।

यदि डेटा को ज्यादातर ऐप में आंतरिक रूप से उपयोग किया जाता है, और आपको क्यूटी से दूर जाने की संभावना नहीं है, तो प्रदर्शन समस्याओं को छोड़कर, क्यूटी कंटेनरों का उपयोग करें क्योंकि यह डेटा के बिट्स बना देगा जो कि यूआई से निपटने के लिए आसान है।

यदि डेटा ज्यादातर अन्य पुस्तकालयों के साथ संयोजन में उपयोग किया जाता है जो केवल एसटीएल कंटेनरों के बारे में जानते हैं, तो एसटीएल कंटेनरों का उपयोग करें। यदि आपके पास यह स्थिति है तो आप किसी समस्या में नहीं हैं क्योंकि आप कंटेनर प्रकारों के बीच आगे और पीछे बहुत कुछ करने जा रहे हैं, चाहे आप कुछ भी करें।


7

गाय अंतर के अलावा, एसटीएल कंटेनर प्लेटफॉर्म की एक किस्म पर बहुत अधिक व्यापक रूप से समर्थित हैं। यदि आप अपने काम को "मुख्यधारा" प्लेटफार्मों तक सीमित करते हैं, तो Qt काफी पोर्टेबल है, लेकिन STL कई अन्य अधिक अस्पष्ट प्लेटफार्मों (जैसे, टेक्सास इंस्ट्रूमेंट्स डीएसपी) पर भी उपलब्ध है।

क्योंकि एसटीएल एकल निगम द्वारा नियंत्रित होने के बजाय मानक है, आम तौर पर बोलने वाले, अधिक प्रोग्रामर जो आसानी से पढ़ सकते हैं, समझ सकते हैं और एसटीएल कोड और अधिक संसाधनों (पुस्तकों, ऑनलाइन मंचों, सम्मेलनों, आदि) को संशोधित कर सकते हैं। ऐसा करने से Qt के लिए कर रहे हैं। यह कहने के लिए नहीं है कि अकेले इस कारण से क्यूटी से दूर भागना चाहिए; बस, अन्य सभी चीजें समान हो रही हैं, आपको एसटीएल के लिए डिफ़ॉल्ट होना चाहिए, लेकिन निश्चित रूप से सभी चीजें शायद ही कभी समान होती हैं, इसलिए आपको अपने स्वयं के संदर्भ में फैसला करना होगा जो सबसे अधिक समझ में आता है।

एलेक्सकेआर के जवाब के संबंध में: एसटीएल प्रदर्शन की सीमा के भीतर गारंटी है, लेकिन किसी दिए गए कार्यान्वयन से उनके एसटीएल को गति देने के लिए प्लेटफ़ॉर्म-निर्भर विवरण का उपयोग हो सकता है । तो इस अर्थ में, आपको विभिन्न प्लेटफार्मों पर अलग-अलग परिणाम मिल सकते हैं, लेकिन यह स्पष्ट गारंटी (मोडुलो बग) की तुलना में कभी भी धीमा नहीं होगा।


9
अपने पहले बिंदु के संबंध में: मेरा मानना ​​है कि ओपी उन परियोजनाओं की बात कर रहा है जो पहले से ही क्यूटी का उपयोग करती हैं, और इसलिए पहले से ही "मुख्यधारा" प्लेटफार्मों तक सीमित हैं। ऐसा लगता नहीं है कि कोई इतनी भारी पुस्तकालय में क्यूटी के रूप में अपने कंटेनर वर्गों के लिए खींच लेगा।
ThisSuitIsBlackNot

4

मेरे पांच सेंट: क्यूटी कंटेनरों को विभिन्न प्लेटफार्मों पर समान काम करना चाहिए। जबकि एसटीएल कंटेनर एसटीएल कार्यान्वयन पर निर्भर करते हैं। आपको विभिन्न प्रदर्शन परिणाम मिल सकते हैं।

संपादित करें: मैं यह नहीं बता रहा कि एसटीएल "धीमा" है, लेकिन मैं विभिन्न कार्यान्वयन विवरणों के प्रभावों की ओर इशारा करता हूं।
जांच करें यह शायद, और फिर यह
और यह एसटीएल की वास्तविक समस्या नहीं है। यदि आप प्रदर्शन में महत्वपूर्ण अंतर रखते हैं, तो कोड में समस्या है जो एसटीएल का उपयोग करता है।


एसटीएल कंटेनर कार्यान्वयन के बावजूद सभी समान हैं। आप एक वेक्टर को पर्दे के पीछे की सूची की तरह लागू नहीं कर सकते क्योंकि यह स्मृति के एक सन्निहित ब्लॉक में होना चाहिए। एसटीएल भी आमतौर पर सभी प्रमुख प्लेटफार्मों पर विशाल विस्तार के लिए अनुकूलित है।
याकूब

1
यदि आप एसटीएल के वादों से चिपके रहते हैं (यह मानने के बजाय कि इसे कैसे लागू किया जाता है) तो आपको एसटीएल के साथ प्लेटफार्मों के बीच बढ़ने में कोई समस्या नहीं होगी। Qt के साथ भी।
माइकल कोहेन

यह सच के बिल्कुल विपरीत है। एसटीएल कंटेनर हमेशा सभी प्लेटफार्मों पर समान काम करते हैं; यदि वे नहीं करते हैं, तो वे एसटीएल नहीं हैं। क्यूटी, हालाँकि, वर्जन से वर्जन में काफी बदलाव करता है, इसलिए क्यूटी ४., के बजाय क्यूटी ४.० वाले प्लेटफॉर्म पर आप कुछ गंभीर बदलाव ला सकते हैं।
एलिस

आप दो बहुत भिन्न प्रकार के प्रदर्शनों को भ्रमित कर रहे हैं; एल्गोरिथम प्रदर्शन और व्यावहारिक कम्प्यूटेशनल प्रदर्शन। सभी एसटीएल कार्यान्वयन समान एल्गोरिथम प्रदर्शन की गारंटी देते हैं; यदि आपका वेक्टर किसी तत्व को अनुक्रमित करने के लिए लॉग (n) समय लेता है, तो वह STL वेक्टर नहीं है। आपके लिंक व्यावहारिक कम्प्यूटेशनल प्रदर्शन की ओर इशारा करते हैं, जो इस चर्चा में अर्थहीन है; क्यूटी संस्करणों के बीच अपने एल्गोरिदम को बदलता है, और विभिन्न प्लेटफार्मों पर एक ही सी ++ को अलग-अलग प्रदर्शन मिलता है। ये मेरे अनुभव में, एसटीएल प्रदर्शन में अंतर से कहीं अधिक निंदनीय हैं।
एलिस

3

मुझे लगता है कि यह उस तरीके पर निर्भर करता है जिस तरह से आप क्यूटी का उपयोग करते हैं। यदि आप इसे अपने उत्पाद से अधिक उपयोग करते हैं, तो संभवतः यह क्यूटी कंटेनरों का उपयोग करने के लिए समझ में आता है। यदि आप इसे केवल यूआई भाग के लिए (उदाहरण के लिए) समाहित करते हैं, तो C ++ मानक कंटेनरों का उपयोग करना बेहतर हो सकता है।


3

मेरा विचार है कि एसटीएल एक उत्कृष्ट सॉफ्टवेयर है, लेकिन अगर मैं कुछ केडीई या क्यूटी संबंधित प्रोग्रामिंग कर रहा हूं तो क्यूटी जाने का रास्ता है। इसके अलावा, यह आपके द्वारा उपयोग किए जा रहे कंपाइलर पर निर्भर करता है, जीसीसी एसटीएल के साथ बहुत अच्छा काम करता है, लेकिन अगर आपको सन स्टूडियो सीसी का उपयोग करना है तो एसटीएल आपको एसटीएल प्रति एसटीएल न होने के कारण कंपाइलर के कारण सिरदर्द पैदा करेगा। उस मामले में जब से कंपाइलर आपके सिर को चोट पहुंचाएगा बस आपको परेशानी से बचाने के लिए क्यूटी का उपयोग करें। बस मेरे 2 सेंट ...


3

QVector में एक (कभी-कभी) बड़ी सीमा होती है। यह केवल मेमोरी के इंट बाइट्स को आवंटित कर सकता है (ध्यान दें कि सीमा बाइट्स में है तत्वों की संख्या में नहीं)। तात्पर्य यह है कि QVector के साथ ~ 2GB से बड़े मेमोरी के सन्निहित ब्लॉक को आवंटित करने की कोशिश करने से दुर्घटना हो सकती है। यह Qt 4 और 5 के साथ होता है। std :: वेक्टर में ऐसी कोई सीमा नहीं है।


0

मेरे लिए एसटीएल कंटेनरों के साथ जाने का मुख्य कारण यह है कि यदि आपको बहुत बड़े कंटेनरों में मेमोरी का पुन: उपयोग करने के लिए कस्टम आवंटनकर्ता की आवश्यकता है। उदाहरण के लिए मान लें कि आपके पास एक QMap है जो 1000000 प्रविष्टियों (कुंजी / मूल्य जोड़े) को संग्रहीत करता है। Qt में इसका तात्पर्य है कि 1000000 मिलियन आवंटन ( newकॉल) कोई फर्क नहीं पड़ता। एसटीएल में आप हमेशा एक कस्टम एलोकेटर बना सकते हैं जो आंतरिक रूप से उस मेमोरी को एक ही बार में आवंटित करता है और इसे मैप में आबादी के रूप में प्रत्येक प्रविष्टि को असाइन करता है।

मेरी सलाह यह है कि व्यावसायिक तर्क में प्रदर्शन महत्वपूर्ण एल्गोरिदम लिखते समय एसटीएल कंटेनरों का उपयोग करें और फिर जब परिणाम आपके यूआई नियंत्रण और रूपों द्वारा प्रदर्शित हों, तो जरूरत पड़ने पर उन्हें क्यूटी कंटेनरों में बदल दें।


नहीं यहाँ QTL की रक्षा करने की कोशिश कर, लेकिन आप सकता विशेषज्ञ QMapNode<K,V>आपके लिए K, Vअपने खुद के प्रदान करने के लिए operator new
मार्क मुत्ज़ - mmutz
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.