C ++ 11 में "वापसी {}" कथन का क्या अर्थ है?


115

क्या बयान देता है

return {};

C ++ 11 में इंगित करें, और इसका उपयोग करने के लिए कब (कहना)

return NULL;

या

return nullptr;

59
यह फ़ंक्शन के रिटर्न प्रकार का डिफ़ॉल्ट-निर्मित उदाहरण देता है।
रिचर्ड होजेस

या यह return;मूल्य के बिना सरल है ?
--६

नहीं, जैसा कि चर्चा से पता चलता है, यह एक संकलन-समय की त्रुटि है यदि आपके फ़ंक्शन को कुछ वापस करना चाहिए (यानी शून्य रिटर्न प्रकार का नहीं) और आप लिखते हैं return; दूसरी तरफ return{};यदि आपके पास वापसी प्रकार है तो मान्य है।
पीडिया

@Pedia हमेशा नहीं, कुछ ऑब्जेक्ट को निर्माण के लिए तर्कों की आवश्यकता होगी
MM

जवाबों:


108

return {};इंगित करता है "एक खाली सूची-आरंभीकरण के साथ आरंभ किए गए फ़ंक्शन के रिटर्न प्रकार का एक ऑब्जेक्ट "। सटीक व्यवहार लौटे ऑब्जेक्ट के प्रकार पर निर्भर करता है।

से cppreference.com (ओ पी सी ++ 11 टैग है क्योंकि, मैं सी ++ 14 और सी ++ 17 में नियमों को बाहर रखा गया, अधिक जानकारी के लिए लिंक देखें):

  • यदि ब्रेडेड-इनिट-सूची खाली है और T एक डिफ़ॉल्ट कंस्ट्रक्टर के साथ एक वर्ग प्रकार है, तो मूल्य-आरंभीकरण किया जाता है।
  • अन्यथा, यदि T एक समुच्चय प्रकार है, तो कुल आरंभ किया जाता है।
  • अन्यथा, यदि T std का एक विशेषज्ञता है :: initializer_list, T ऑब्जेक्ट डायरेक्ट-इनिशियलाइज़्ड या कॉपी-इनिशियलाइज़्ड है, जो संदर्भ के आधार पर, ब्रेस-इन-लिस्ट से है।
  • अन्यथा, T के निर्माता दो चरणों में माने जाते हैं:

    • सभी निर्माता जो std लेते हैं :: initializer_list केवल तर्क के रूप में, या पहले तर्क के रूप में यदि शेष तर्कों में डिफ़ॉल्ट मान हैं, तो जांच की जाती है और प्रकार std के एकल तर्क के खिलाफ अधिभार संकल्प द्वारा मिलान किया जाता है :: initializer_list
    • यदि पिछला चरण एक मैच का उत्पादन नहीं करता है, तो टी के सभी कंस्ट्रक्टर ओवरलोड रिज़ॉल्यूशन में उन तर्कों के सेट के खिलाफ भाग लेते हैं जिनमें ब्रेडेड-इनिट-लिस्ट के तत्व शामिल हैं, इस प्रतिबंध के साथ कि केवल गैर-संकीर्ण रूपांतरणों की अनुमति है। यदि यह चरण एक कॉपी-लिस्ट-इनिशियलाइज़ेशन के लिए सबसे अच्छा मेल के रूप में एक स्पष्ट कंस्ट्रक्टर का उत्पादन करता है, तो संकलन विफल हो जाता है (ध्यान दें, सरल कॉपी-इनिशियलाइज़ेशन में, स्पष्ट कंस्ट्रक्टरों पर विचार नहीं किया जाता है)।
  • अन्यथा (यदि टी एक वर्ग प्रकार नहीं है), यदि लट-इन-सूची में केवल एक तत्व है और या तो टी एक संदर्भ प्रकार नहीं है या एक संदर्भ प्रकार है जो तत्व के प्रकार के साथ संगत है, टी प्रत्यक्ष है- initialized (डायरेक्ट-लिस्ट-इनिशियलाइज़ेशन में) या copy-initialized (कॉपी-लिस्ट-इनिशियलाइज़ेशन में), सिवाय इसके कि संकीर्ण रूपांतरणों की अनुमति नहीं है।

  • अन्यथा, यदि T एक संदर्भ प्रकार है जो तत्व के प्रकार के साथ संगत नहीं है। (यह विफल रहता है यदि संदर्भ एक गैर-कॉन्स्टेबल अंतराल संदर्भ है)
  • अन्यथा, यदि ब्रेडेड-इनिट-सूची में कोई तत्व नहीं है, तो टी मूल्य-प्रारंभिक है।

C ++ 11 से पहले, एक समारोह में लौटने के लिए std::string, आपने लिखा होगा:

std::string get_string() {
    return std::string();
}

C ++ 11 में ब्रेस सिंटैक्स का उपयोग करना, आपको टाइप दोहराने की आवश्यकता नहीं है:

std::string get_string() {
    return {}; // an empty string is returned
}

return NULLऔर return nullptrजब फ़ंक्शन पॉइंटर प्रकार देता है तो इसका उपयोग किया जाना चाहिए:

any_type* get_pointer() {
    return nullptr;
}

हालाँकि, NULLC ++ 11 के बाद से हटा दिया गया है क्योंकि यह पूर्णांक मान (0) के लिए केवल एक उपनाम है, जबकि nullptrएक वास्तविक सूचक प्रकार है:

int get_int() {
    return NULL; // will compile, NULL is an integer
}

int get_int() {
    return nullptr; // error: nullptr is not an integer
}

91

यह शायद भ्रामक है:

int foo()
{
  return {};   // honestly, just return 0 - it's clearer
}

यह शायद नहीं है:

SomeObjectWithADefaultConstructor foo()
{
  return {};
  // equivalent to return SomeObjectWithADefaultConstructor {};
}

9
तो, यह एक संकलित समय त्रुटि है यदि रिटर्न प्रकार में डिफ़ॉल्ट निर्माता नहीं है, सही है?
पीडिया

10
यह एक संकलित त्रुटि है यदि रिटर्न प्रकार एक वर्ग है जिसमें एक गैर-स्पष्ट डिफ़ॉल्ट निर्माता नहीं है और एक समुच्चय नहीं है।
ओकेटलिस्ट

3
यदि प्रकार में एक initializer_listकंस्ट्रक्टर है, तो क्या इसका उपयोग नहीं किया जाएगा यदि कोई डिफ़ॉल्ट कंस्ट्रक्टर उपलब्ध नहीं है?
celtschk

4
"शायद भ्रमित"? क्या यही कारण है कि कुछ अनाम आत्मा को "कि फूला हुआ अश्लीलता कि C ++" कहा जाता है? क्या कीस्ट्रोक्स में जो कुछ भी बचत होती है, वह संभवतः इसे प्रदान करने वाली स्पष्टता की कमी की संभावना को सही ठहराती है? यह एक ईमानदार सवाल है। कृपया मुझे व्यावहारिक उदाहरणों के साथ मनाएं।
मिकीफ़ेगैन_एफ़रExitOfSO

4
return {}के बराबर नहीं हैreturn SomeObjectWithADefaultConstructor{};
MM

26

return {};इसका मतलब है कि रिटर्न वैल्यू{} का इनिशियलाइज़र है । रिटर्न वैल्यू लिस्ट-इनिशियलाइज्ड विद अ खाली लिस्ट है।


यहाँ C ++ मानक में [stmt.return] के आधार पर वापसी मूल्य पर कुछ पृष्ठभूमि दी गई है :

किसी फ़ंक्शन के लिए जो मान से लौटता है (यानी रिटर्न प्रकार एक संदर्भ नहीं है और नहीं है void), एक अस्थायी ऑब्जेक्ट है जिसे रिटर्न वैल्यू कहा जाता है । यह ऑब्जेक्ट returnस्टेटमेंट द्वारा बनाया गया है , और इसके शुरुआती लोग इस पर निर्भर करते हैं कि रिटर्न स्टेटमेंट में क्या था।

रिटर्न मान उस फ़ंक्शन में पूर्ण-अभिव्यक्ति के अंत तक जीवित रहता है जिसे फ़ंक्शन कहा जाता है; यदि इसका वर्ग प्रकार होता है, तो इसका विध्वंसक भाग तब तक चलेगा जब तक कि इसे आजीवन विस्तारित नहीं किया जाता है, जब यह सीधे किसी संदर्भ को बाध्य करता है।

वापसी मूल्य को दो अलग-अलग तरीकों से शुरू किया जा सकता है:


मान लें Tकि फ़ंक्शन का रिटर्न प्रकार है, तो ध्यान दें कि return T{};अलग है return {}: पूर्व में, एक अस्थायी T{}बनाया गया है, और उसके बाद रिटर्न मान उस अस्थायी से प्रतिलिपि-प्रारंभ किया गया है।

यह संकलित करने में विफल होगा यदि Tकोई सुलभ प्रतिलिपि / चाल-निर्माणकर्ता नहीं है, लेकिन return {};उन निर्माणकर्ताओं के मौजूद न होने पर भी सफल होगा। तदनुसार, return T{};कॉपी-कंस्ट्रक्टर आदि के साइड-इफेक्ट दिखा सकते हैं, हालांकि यह एक कॉपी एलिसेंस संदर्भ है इसलिए ऐसा नहीं हो सकता है।


यहाँ C ++ 14 (N4140 [dcl.init.list] / 3) में सूची-आरंभीकरण का संक्षिप्त विवरण दिया गया है, जहाँ इनिशियलाइज़र एक खाली सूची है:

  • यदि Tएक समुच्चय है, तो प्रत्येक सदस्य को इसके ब्रेस-या-इक्वलाइज़र से इनिशियलाइज़ किया जाता है यदि यह एक था, अन्यथा जैसे कि {} (इसलिए इन चरणों को पुनरावर्ती रूप से लागू करें)।
  • यदि Tउपयोगकर्ता-प्रदान किए गए डिफ़ॉल्ट निर्माता के साथ एक वर्ग प्रकार है, तो उस निर्माता को कहा जाता है।
  • यदि Tएक वर्ग प्रकार एक अंतर्निहित परिभाषित या = defaultएड डिफॉल्ट कंस्ट्रक्टर के साथ होता है, तो ऑब्जेक्ट को शून्य-आरंभीकृत किया जाता है और फिर डिफॉल्ट कंस्ट्रक्टर को कहा जाता है।
  • यदि Tकोई है std::initializer_list, तो रिटर्न वैल्यू एक खाली सूची है।
  • अन्यथा (यानी Tएक गैर-श्रेणी प्रकार है - रिटर्न प्रकार को एरेज़ नहीं किया जा सकता है), रिटर्न मान शून्य-प्रारंभिक है।

एग्रीगेट इनिट पहले आता है, और यह हर सदस्य के साथ पुनरावृत्ति करता है {}, जो वैल्यू-इन हो सकता है या नहीं।
टीसी

@ सही है, मैं संयोग से गया था लेकिन "C ++ 14 तक" को नजरअंदाज कर दिया
MM

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.