2015-01-03 16 views
7

में, कोई फ़ंक्शन में पैरामीटर प्रारंभ करने के लिए प्रारंभकर्ता सूचियों का उपयोग कर सकता है। इसका उद्देश्य क्या है? क्या कॉन्स वैक्टर के साथ ऐसा नहीं किया जा सकता है? नीचे दो कार्यक्रमों का अंतर क्या है? स्थिरांक वेक्टर का उपयोगप्रारंभकर्ता सूची बनाम वेक्टर

#include <iostream> 

using namespace std; 

int sumL(initializer_list<int> l){ 
    int sum = 0; 
    for (const auto i: l){ 
     sum += i; 
    } 
    return sum; 
} 

int main(){ 

    cout << sumL({1, 2, 3}) << "\n"; 

    return 0; 
} 

:

प्रारंभकर्ता सूची का उपयोग करना

#include <iostream> 
#include <vector> 

using namespace std; 

int sumV(const vector<int> l){ 
    int sum = 0; 
    for (const auto i: l){ 
     sum += i; 
    } 
    return sum; 
} 

int main(){ 

    cout << sumV({1, 2, 3}) << "\n"; 

    return 0; 
} 
+2

दूसरे कोड को आवश्यकतानुसार अधिक आवश्यकता होती है (और वेक्टर को प्रारंभिककर्ता_सूची भी सूखता है) –

+0

ऑफटॉपिक: ध्यान दें कि आप वेक्टर की एक प्रति बनाते हैं, यानी, आपने संदर्भ का उपयोग नहीं किया है। लूप के लिए वही है, अब यह केवल एक int है लेकिन बड़ी वस्तुओं के साथ संदर्भ से बच जाएगा कि आप प्रत्येक ऑब्जेक्ट को वेक्टर में कॉपी करते हैं। – Michiel

उत्तर

6

std::initializer_list का आम उपयोग कंटेनर (और इसी तरह) कक्षाओं के निर्माताओं के लिए तर्क के रूप में है, उन कंटेनरों की सुविधाजनक initialisation की इजाजत दी एक ही प्रकार की कुछ वस्तुओं से। बेशक, आप अन्यथा std::initializer_list का उपयोग कर सकते हैं और फिर उसी {} सिंटैक्स का उपयोग कर सकते हैं।

के बाद से एक std::initializer_list एक निश्चित आकार है, यह गतिशील आवंटन की आवश्यकता नहीं है और इसलिए कुशलता से लागू किया जा सकता। दूसरी ओर, std::vector, गतिशील स्मृति आवंटन की आवश्यकता है। यहां तक ​​कि आपके सरल उदाहरण में यह असंभव है कि संकलक इस ओवरहेड को अनुकूलित करेगा (मध्यस्थ std::vector और इसकी गतिशील स्मृति आवंटन से बचें)। इसके अलावा, आपके कार्यक्रमों के नतीजे में कोई अंतर नहीं है (हालांकि आपको प्रतिलिपि और इसके संबंधित गतिशील स्मृति आवंटन से बचने के लिए const std::vector<int>& तर्क लेना चाहिए)।

3

दोनों के अर्थशास्त्र काफी अलग हैं। initializer_list में पॉइंटर अर्थशास्त्र है जबकि vector में मूल्य semantics है।

int const __temp_array[3] = {1, 2, 3}; 
cout << sumL(std::initializer_list<int>(__temp_array, __temp_array + 3)) << "\n"; 

यह [dcl.init.list]/5 में समझाया गया है:

अपने पहले उदाहरण में, संकलक निम्न के समान कोड जनरेट करेगा। आप देख सकते हैं, sumL भीतर आप braced-init-सूची के तत्वों को const संकेत की पहुंच है, यह आपके अलावा कोई विकल्प नहीं सूची से बाहर तत्वों नकल करने के लिए है का मतलब है।

sumV के मामले में आप अगर जरूरत std::movedvector से तत्वों कर सकती थीं (पैरामीटर प्रकार यह सोचते हैं const नहीं है)।

इसी प्रकार, initializer_list की प्रतिलिपि उथली प्रतियां करता है, यानी vector की प्रतिलिपि बनाते समय केवल पॉइंटर्स की प्रतिलिपि बनाई जाएगी, इसका मतलब है कि तत्वों की प्रतिलिपि बनाई जाएगी।

आपके उदाहरण में, vector के निर्माण के अलावा initializer_list का निर्माण करते समय, ऊपर दिए गए कोई भी अंक वास्तव में कोई फर्क नहीं पड़ता है।

3

initializer_list इष्टतम भंडारण स्थान का उपयोग करता है और अनावश्यक कॉल रोकता है, इसे हल्के वजन के लिए डिज़ाइन किया गया है, जबकि vector के साथ एक ढेर आवंटन है और वहां अधिक प्रतियां/चालें हो सकती हैं।

1

initalizer_list std :: वेक्टर की तरह एक सामान्यीकृत कंटेनर नहीं है। इसका प्राथमिक उद्देश्य ऑब्जेक्ट प्रारंभिक है। यदि कम ओवरहार्ड और कोई ढेर आवंटन आपके लिए आकर्षक नहीं है तो मैं std :: array को देखने का सुझाव दूंगा। यह एक निश्चित आकार का स्टैक आवंटित सरणी है जिसमें एक एसटीएल कंटेनर की सभी सुविधाएं हैं, जो अनिवार्य रूप से एक सी-सरणी के शीर्ष पर एक पतली आवरण है।

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