2011-08-18 32 views
17

std::initializer_list संकलक द्वारा एक ब्रेस-संलग्न इनिट सूची से बनाया गया है और इस सूची का आकार संकलन समय निरंतर होना चाहिए।आकार std :: startizer_list का टेम्पलेट तर्क क्यों नहीं है?

तो समिति ने टेम्प्लेट तर्कों से आकार को हटाने का फैसला क्यों किया? यह संभवतः कुछ अनुकूलन को रोकता है और कुछ चीजों को असंभव बनाता है (को std::initializer_list से प्रारंभ करना)।

+4

एक बहुत ही इसी तरह के सवाल यह है कि "क्यों' std :: initializer_list :: size' नहीं 'constexpr' (अब) है?" जिसे एक साल पहले क्लर्क ++ एम पर पूछा गया था। – MSalters

+1

रे एमएसल्टर्स की 2011 टिप्पणी, ध्यान दें कि सी ++ 14 * करता है * 'std :: startizer_list :: size' को 'constexpr' फ़ंक्शन' बनाता है, भले ही C++ 11 नहीं था। http://en.cppreference.com/w/cpp/utility/initializer_list/size – Quuxplusone

उत्तर

7

मौजूदा सिस्टम का एक उलझन यह है कि आप उन कार्यों को निर्यात कर सकते हैं जो एक DLL से initializer_list लेते हैं। यदि यह आकार पर टेम्पलेट किया गया था, तो उन्हें स्रोत के रूप में भेजना होगा।

+4

समान पंक्तियों के साथ: यह कुछ गैर-तुच्छ ब्लोट का कारण बन सकता है। – MSalters

13

तो initializer_liststd::initializer_list<type, size> रूप में परिभाषित किया गया था, तो किसी भी समारोह है कि एक initializer_list<type> ले जाता है, जहां type कुछ ठोस प्रकार है, अब एक टेम्पलेट है कि सूची के आकार के आधार पर समारोह होना जरूरी होगा। या उन्हें एक विशिष्ट प्रकार और आकार के initializer_list पास करने की आवश्यकता होगी।

इनमें से दोनों बहुत अस्वीकार्य हैं। सभी लोग अपने सभी कोड टेम्पलेट्स के रूप में नहीं लिखते हैं।

आप एक ब्रेस्ड-इनिट-सूची ({} मध्य में सामान के साथ) std::array प्रारंभ कर सकते हैं। लेकिन यह std::intiializer_list जैसा ही नहीं है। array कक्षा एक कुल प्रकार है। यह एक संरचना है जिसमें एक तत्व होता है, जो एक सार्वजनिक सरणी है। इसलिए, एक अनुरूप सी ++ 11 कार्यान्वयन पर, इस संकलन करना चाहिए:

std::array<int, 3> myArray = {1, 3, 5}; 

हालांकि, {1, 3, 5} एक std::initializer_list वस्तु नहीं है, यह केवल एक ब्रेसिड-इनिट-लिस्ट है, जिसका उपयोग उपयुक्त प्रकारों को शुरू करने के लिए किया जा सकता है।

आप एक std::initializer_list वस्तु एक aggegate के निर्माता के लिए बस के रूप में आप किसी भी struct के लिए होगा पारित कर सकते हैं नहीं (क्योंकि समुच्चय कोई कंस्ट्रक्टर्स है), लेकिन आप एक std::array प्रारंभ करने में कुल प्रारंभ आह्वान करने के लिए एक braced-init-सूची का उपयोग कर सकते हैं, एक सरणी युक्त

एक std::initializer_list और एक braced-init-सूची के बीच का अंतर एक int और शाब्दिक 0 के बीच अंतर की तरह एक सा है। यह आमतौर पर int ऑब्जेक्ट को पॉइंटर प्रकार में परिवर्तित करने के लिए कानूनी नहीं है, लेकिन यह एक पूर्णांक अक्षर 0 को एक सूचक प्रकार में रूपांतरित करने के लिए कानूनी है। जिस तरह से braced-init-सूचियों काम है कि तरह है:

int i = 0; //Legal 
void *j = 0; //Legal 
void *k = i; //Not legal 

std::array<int, 3> myArray = {1, 3, 5};    //Legal 
std::initializer_list<int> myInitList = {1, 3, 5}; //Legal 
std::array<int, 3> myArray = myInitList;   //Not legal 
+0

क्या आप 'std :: arrayizer से 'std :: array' को प्रारंभ करने के बारे में निश्चित हैं? 'सर x = {1,2,3}' जीसीसी 4.6 पर काम नहीं करता है और मैं अनुमान नहीं लगा सकता कि यह n3242 से काम करना चाहिए। – pmr

+0

@pmr: std :: सरणी को एक संरचना के रूप में परिभाषित किया गया है (N3291 में), और यह कुल प्रकार के लिए C++ 0x नियमों का पालन करता है। इसलिए, इसे कुल प्रारंभिकरण के माध्यम से शुरू किया जाना चाहिए। तो आप इसे प्रारंभ करते हैं जैसे कि यह एक तत्व था जिसमें 3 तत्वों की सरणी थी। मैं इसे समझाने के लिए अपनी पोस्ट अपडेट करूंगा। –

+1

@ निकोल: यह केवल कुल प्रारंभिक है - 'startizer_list' पूरी तरह से ऑर्थोगोनल है। – ildjarn

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