सी ++ ऑटो और बनाम ऑटो


91

स्थानीय चर बनाते समय, क्या इसका उपयोग करना सही है (const) auto&या auto?

उदाहरण के लिए:

SomeClass object;
const auto result = object.SomeMethod();

या const auto& result = object.SomeMethod();

जहाँ SomeMethod () एक गैर-आदिम मान लौटाता है - शायद दूसरा उपयोगकर्ता-परिभाषित प्रकार। मेरी समझ यह है कि const auto& resultSomeMethod () द्वारा लौटाए गए परिणाम के बाद से सही है, लौटे हुए प्रकार के लिए कॉपी कंस्ट्रक्टर को कॉल करेगा। यदि मैं गलत हूं तो मुझे बताएं।

आदिम प्रकारों के बारे में क्या? मुझे लगता है const auto sum = 1 + 2;कि सही है।

क्या यह छोरों के लिए सीमा के आधार पर भी लागू होता है?

for(const auto& object : objects)

1
मैं आपको इसे पढ़ने के लिए अत्यधिक सलाह देता हूं: safaribooksonline.com/library/view/effective-modern-c/… ... पहले दो अध्याय स्वतंत्र हैं और टेम्पलेट प्रकार की कटौती का वर्णन करते हैं, जो अनिवार्य रूप से autoकाम करता है ( initializer_listएस के अजीबोगरीब मामले को छोड़कर) एक टेम्पलेट संदर्भ में गैर- autoकटौती ), फिर कटौती टाइप करें।
vsoftco

जवाबों:


107

autoऔर auto &&अधिकांश मामलों को कवर करें:

  • autoजब आपको स्थानीय प्रतिलिपि की आवश्यकता हो तब उपयोग करें । यह कभी भी एक संदर्भ उत्पन्न नहीं करेगा। कॉपी (या चाल) कंस्ट्रक्टर का अस्तित्व होना चाहिए, लेकिन कॉपी एलिजन ऑप्टिमाइज़ेशन के कारण इसे कॉल नहीं किया जा सकता है ।

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

    इसके अलावा, auto &&इस बात की गारंटी नहीं है कि वह वस्तु संशोधित करने योग्य होगी या तो। किसी constवस्तु या संदर्भ को देखते हुए , यह कटौती करेगा const। हालांकि, विशिष्ट संदर्भ को देखते हुए, परिवर्तनशीलता को अक्सर मान लिया जाता है।

auto &और auto const &थोड़ा और विशिष्ट हैं:

  • auto &गारंटी देता है कि आप चर को किसी और चीज के साथ साझा कर रहे हैं। यह हमेशा एक संदर्भ है और एक अस्थायी के लिए कभी नहीं।

  • auto const &पसंद है auto &&, लेकिन केवल-पढ़ने के लिए पहुँच प्रदान करता है।

आदिम / गैर-आदिम प्रकारों के बारे में क्या?

इसमें कोई फर्क नही है।

क्या यह छोरों के लिए सीमा के आधार पर भी लागू होता है?

हाँ। उपरोक्त सिद्धांतों को लागू करना,

  • auto &&लूप के भीतर अनुक्रम के मूल्यों को संशोधित करने और त्यागने की क्षमता के लिए उपयोग करें । (यही है, जब तक कि कंटेनर केवल एक रीड-ओनली व्यू प्रदान नहीं करता है, जैसे कि std::initializer_list, किस स्थिति में यह प्रभावी रूप से होगा auto const &।)
  • auto &अनुक्रम के मूल्यों को सार्थक तरीके से संशोधित करने के लिए उपयोग करें ।
  • auto const &केवल पढ़ने के लिए उपयोग करें ।
  • auto(परिवर्तनीय) प्रतियों के साथ काम करने के लिए उपयोग करें ।

आप auto constबिना किसी संदर्भ के भी उल्लेख करते हैं। यह काम करता है, लेकिन इसका आमतौर पर उपयोग नहीं किया जाता है क्योंकि शायद ही कभी किसी चीज को पढ़ने के लिए एक फायदा होता है जो आपके पास पहले से ही है।


सटर का कहना है कि ऑटो और पटरियों में स्थिरता
जेसी काली मिर्च

1
@JessePepper हां। (हालांकि प्राधिकरण के लिए अपील करना थोड़ा अजीब है।) क्या आप इसके किसी विशेष हिस्से की बात कर रहे हैं?
पोटाटोज़वॉटर

संक्षेप में auto&एक अच्छा विकल्प लगता है। लेकिन const auto&जब आप पहले से ही नहीं है तो आप निरंतरता जोड़ना चाहते हैं। auto&&फॉरवर्ड करने के लिए, जो मुझे लगता है कि सटर के विचार से अधिक बार होता है। उदाहरण के लिए, आप auto&&दो मानों तक रिटर्न वैल्यू जमा करना चाहते हैं और फिर इसे दो चीजों में "फॉरवर्ड" कर सकते हैं, जैसे डीबगिंग के लिए वैल्यू देखने के लिए और इसे किसी अन्य फंक्शन में पास करना। मैंने ऑटो और& का उपयोग अधिक बार किया लेकिन कुछ अप्रत्याशित चीजों को करने पर इसे एक या दो बार काट लिया गया। काश मैंने और नोटिस किया जो गलत हो गया!
जेसी काली मिर्च

@JessePepper हां, auto&&एक लापता भाषा सुविधा से संबंधित है, जिसे किसी भी बयान को छोटे बयानों में विभाजित करने की अनुमति देनी चाहिए । लापता हिस्सा जीवनकाल विस्तार है ... मैंने इसे ठीक करने में काफी प्रयास किया लेकिन किसी ने गौर नहीं किया।
पंडित्री

ऑटो कास्ट पर: ऑटो कॉन्स्टेंट x = fn () लिखना अधिक स्वाभाविक हो सकता है; यदि आप जानते हैं कि फ़ंक्शन संदर्भ नहीं लौटाता है, और आप चाहते हैं कि ऑब्जेक्ट x न बदले, बग से बचने के लिए, या दस्तावेज़ को इस दायरे में उपयोग करें। उसी तरह आप सामान्य रूप से नहीं लिखेंगे: const int & x = 1; लेकिन ऑटो कॉन्स्टेंट इस तरह घोषित किए गए संदर्भों के लिए आजीवन विस्तार नियमों के कारण बराबर परिणाम देता है।
Spacen Jasset

47

हाँ, यह उपयोग करने के लिए सही है autoऔर auto&स्थानीय चर के लिए। किसी फ़ंक्शन का रिटर्न प्रकार प्राप्त करते समय, इसका उपयोग करना भी सही है auto&। यह छोरों के लिए भी रेंज पर लागू होता है।

उपयोग करने के सामान्य नियम autoहैं:

  • auto xजब आप प्रतियों के साथ काम करना चाहते हैं तब चुनें ।
  • चुनें auto &xकि आप मूल वस्तुओं के साथ कब काम करना चाहते हैं और उन्हें संशोधित कर सकते हैं।
  • चुनें auto const &xकि आप मूल वस्तुओं के साथ कब काम करना चाहते हैं और उन्हें संशोधित नहीं करेंगे।

आप यहां ऑटो स्पेसियर के बारे में अधिक पढ़ सकते हैं ।


10

autoटाइप डिडक्शन के समान तंत्र को टेम्प्लेट के रूप में उपयोग करता है, एकमात्र अपवाद जो मुझे ब्रेस-इन-लिस्ट के होने के बारे में पता है, जो कि के autoरूप में द्वारा घटाए गए हैं std::initializer_list, लेकिन एक टेम्प्लेट के संदर्भ में गैर- कटौती किए गए हैं ।

auto x = expression;

राइट हैंड साइड एक्सप्रेशन के प्रकार से पहले सभी संदर्भ और cv क्वालिफायर को अलग करके, फिर टाइप से मिलान करके काम करता है। उदाहरण के लिए, यदि आपके पास const int& f(){...}तब के रूप में auto x = f();कटौती xहै int, और नहीं const int&

दूसरा रूप,

auto& x = expression

cv- क्वालीफायर को स्ट्रिप नहीं करता है , इसलिए, ऊपर दिए गए उदाहरण का उपयोग करके, auto& x = f()घटाता xहै const int&। अन्य संयोजन सिर्फ cv क्वालीफायर जोड़ते हैं।

यदि आप चाहते हैं कि आपका प्रकार हमेशा cv-ref क्वालिफायर के साथ घटाया जाए, तो decltype(auto)C ++ 14 में कुख्यात का उपयोग करें , जो कि decltypeप्रकार कटौती नियमों का उपयोग करता है।

इसलिए, संक्षेप में, यदि आप प्रतियां चाहते हैं auto, तो उपयोग करें , यदि आप संदर्भ चाहते हैं , तो उपयोग करें auto&constजब भी आप अतिरिक्तता चाहते हैं, का उपयोग करें const


EDIT एक अतिरिक्त उपयोग मामला है,

auto&& x = expression;

जो संदर्भ-ढहते हुए नियमों का उपयोग करता है, उसी तरह जैसे कि टेम्पलेट कोड में संदर्भ अग्रेषित करने के मामले में। यदि expressionएक लैवल्यू है, तो xcv-क्वालिफायर के साथ एक लैवल्यू संदर्भ है expression। यदि expressionएक रव्वा है, तो xएक रवायु संदर्भ है।


@Potatoswatter धन्यवाद, संपादित। मैं वास्तव में cv के लिए आश्चर्यचकित हूं rvalues। क्या परीक्षण का कोई सरल तरीका है? और आपके पास एक सीवी-योग्य प्रतिद्वंद्विता कैसे हो सकती है? फ़ंक्शन रिटर्न पर cv को छोड़ दिया जाता है।
vsoftco

नहीं, यह फ़ंक्शन रिटर्न पर खारिज नहीं किया गया है। यह सभी स्केलर प्रकार (C ++ 14 [और अन्य संस्करणों] /5 / 6) के प्रचलन के लिए छोड़ दिया गया है। आप फंक्शन कॉल या कास्ट नोटेशन का उपयोग करके एक प्राप्त कर सकते हैं। Cv-योग्य xvalues ​​किसी अन्य चीज़ के समान कार्य करते हैं: auto && x = std::move< const int >( 5 );घोषित करेगा int const && x, हालाँकि वे शायद ही कभी उपयोग किए जाते हैं।
पोटाटोस्वाटर

@Potatoswatter धन्यवाद, आप सही हैं, मेरी गलती है। मैंने पहले PODs के साथ परीक्षण किया, जिस स्थिति में cv को छोड़ दिया गया, और सोचा कि यह सामान्य मामला है। बेशक, इसे खारिज नहीं किया जाना चाहिए, क्योंकि सामान्य तौर पर कोई भी cv को संरक्षित करना चाहता हो सकता है (उदाहरण के लिए, कोई गैर-सदस्य सदस्य फ़ंक्शन को प्रतिफल रिटर्न पर कॉल नहीं कर सकता है)।
vsoftco

अदिश प्रकारों के लिए त्याग दिया गया। POD वर्ग हो सकते हैं। वैसे भी, यह अभिव्यक्ति मॉडल और ऑब्जेक्ट मॉडल के चौराहे का एक हैडिश कोने है।
पोटाटोसवटर

2

स्थानीय चर बनाते समय, ऑटो (ऑटो) या ऑटो (कांस्टेबल) का उपयोग करना सही है?

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

जहाँ SomeMethod () एक गैर-आदिम मान लौटाता है - शायद दूसरा उपयोगकर्ता-परिभाषित प्रकार। मेरी समझ यह है कि Const ऑटो और परिणाम सही है क्योंकि SomeMethod () द्वारा लौटाया गया परिणाम लौटा हुआ प्रकार के लिए प्रतिलिपि निर्माता को कॉल करेगा। यदि मैं गलत हूं तो मुझे बताएं।

कानूनी? हां, कास्ट के साथ। सर्वश्रेष्ठ प्रणालियां? शायद नहीं, नहीं। कम से कम, सी ++ 11 के साथ नहीं। विशेष रूप से नहीं, अगर SomeMethod () से लौटा गया मान पहले से ही अस्थायी है। आप C ++ 11 मूवमेंट शब्दार्थ, कॉपी एलीशन और रिटर्न वैल्यू ऑप्टिमाइज़ेशन के बारे में जानना चाहेंगे: https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by- मूल्य /

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=199

https://isocpp.org/wiki/faq/ctors#return-by-value-optimization

आदिम प्रकारों के बारे में क्या? मैं मान लेता हूं कि ऑटो = 1 + 2; सही है।

हां, यह ठीक है।

क्या यह छोरों के लिए सीमा के आधार पर भी लागू होता है?

(कास्ट ऑटो और ऑब्जेक्ट: ऑब्जेक्ट)

हां, यह भी ठीक है। मैं हर समय काम में इस तरह का कोड लिखता हूं।

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