क्या मुझे नए C ++ 11 'ऑटो' फीचर का इस्तेमाल करना चाहिए, खासकर लूप्स में?


20

autoविशेष रूप से छोरों के लिए, कीवर्ड का उपयोग करने के लिए पेशेवरों / विपक्ष क्या हैं ?

for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
   it->something();
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
   it->second->something();
}

for(auto it = x.begin(); it != x.end(); it++ )
{
   it->??
}

जैसे यदि आप नहीं जानते कि आप एक नक्शा या एक वेक्टर आपको पता नहीं होगा के लिए एक iterator है या नहीं लगता है उपयोग करने के लिए कि firstया secondया वस्तु के बस सीधे पहुँच गुण, नहीं?

यह मुझे कीवर्ड का उपयोग करने के लिए C # बहस की याद दिलाता है var। अब तक मुझे जो धारणा मिल रही है, वह यह है कि C ++ की दुनिया में लोग C # दुनिया की autoतुलना varमें कम लड़ाई वाले कीवर्ड को अपनाने के लिए तैयार हैं । मेरे लिए मेरी पहली वृत्ति यह है कि मैं चर के प्रकार को जानना पसंद करता हूं, ताकि मुझे पता चल सके कि मैं इस पर कौन से संचालन कर सकता हूं।


3
रुको! इस बारे में लड़ाई थी कि क्या उपयोग करना है var? मैंने यह खो दिया।
पीडीआर

21
इससे भी बेहतर, आप केवल उपयोग कर सकते हैं for (auto& it : x)(या संदर्भ के बिना यदि आप कॉपी करना चाहते हैं)
तमसे सजेलेई

7
मुझे लगता है अगर आप की सामग्री पर पुनरावृत्ति करने के लिए एक लूप लिख रहे हैं xऔर आप यह भी नहीं जानते कि क्या xहै, तो आप उस लूप को पहली जगह में नहीं लिखना चाहिए ;-)
nikie

@ फिश: रेंज फॉर-लूप रूल्स, लेकिन मैं पांडित्यपूर्ण होता और किया जाता: 'फॉर (लूप एंड एक्स:)' के बजाय रेंज बेस्ड फॉर-लूप्स का उपयोग करते समय, क्योंकि मुझे लगता है कि ऑटो का उपयोग करना कम जानकारीपूर्ण है। मेरे दिमाग में ऑटो के गलत इस्तेमाल की तरह।
शहीद

Var का उपयोग करने पर लड़ाई थोड़ी मूर्खतापूर्ण थी, खासकर रेट्रोस्पेक्ट में। कार्गो पंथ प्रोग्रामिंग देखें ।
क्रेग

जवाबों:


38

C ++ में प्रेरणाएं अधिक चरम हैं, क्योंकि मेटाप्रोग्रामिंग और अन्य चीजों के कारण C # प्रकारों की तुलना में प्रकार बहुत अधिक जटिल और जटिल हो सकते हैं। autoस्पष्ट रूप से लिखने और पढ़ने और अधिक लचीला / बनाए रखने के लिए तेज़ है। मेरा मतलब है, क्या आप लिखना शुरू करना चाहते हैं

boost::multi_map<NodeType, indexed_by<ordered_unique<identity<NodeType>>, hashed_non_unique<identity<NodeType>, custom_hasher>>::iterator_type<0> it

वह भी पूर्ण प्रकार का नहीं है। मैं एक दो टेम्पलेट तर्क से चूक गया।


8
उदाहरण के लिए +1, लेकिन यह भी "आधुनिक" सी ++ की स्थिति के बारे में कुछ बताता है।
zvrba

22
@ ज़र्बा: हाँ- कि जेनेरिक सुविधाएं C # की तुलना में बहुत अधिक शक्तिशाली हैं।
डेडएमजी

4
यह है कि
टाइपडिफ के

19
@gbjbaanb नहीं, यही autoहै। डिजाइन द्वारा। typedefमदद करता है, लेकिन autoअधिक मदद करता है।
कोनराड रुडोल्फ

1
टाइपडिफ ने इस तर्क को अमान्य कर दिया कि "ऑटो का उपयोग वास्तव में लंबे समय तक नहीं करता है"
माइकल

28

आपके उदाहरण में:

for(auto it = x.begin(); it != x.end(); i++)
{
  it->??
}

xदिखाई देने के लिए एक घोषणा होनी चाहिए । इसलिए प्रकार itस्पष्ट होना चाहिए। यदि प्रकार xस्पष्ट नहीं है, तो विधि बहुत लंबी है, या कक्षा बहुत बड़ी है।


7
इसके अलावा, xएक कंटेनर के लिए एक बहुत ही खराब चर नाम है। कुछ स्थितियों में आप संभवतः (शब्दार्थ रूप से मूल्यवान) नाम को देख सकते हैं और संभावित संचालन का अनुमान लगा सकते हैं।
अधिकतम

@ मोम: केवल xएक सामान्य उदाहरण के रूप में उपयोग किया जाता है, मैं काफी वर्णनात्मक चर नामों का उपयोग करता हूं।
उपयोगकर्ता

@ निश्चित रूप से, मुझे नहीं लगा कि यह एक वास्तविक दुनिया का उदाहरण है;)
अधिकतम

14

आपत्ति ! भरी सवाल।

क्या आप मुझे समझा सकते हैं कि तीसरा कोड इसमें क्यों ??है, फिर भी पहला और दूसरा नहीं? निष्पक्षता के लिए, आपके कोड को निम्नानुसार पढ़ना चाहिए :

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->???
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->second->???
}

वहाँ। आप का उपयोग नहीं किया, भले ही एक ही समस्या auto

और सभी मामलों में, उत्तर एक ही है: प्रसंग मायने रखता है । आप सार्थक रूप से अलगाव में कोड के एक टुकड़े के बारे में बात नहीं कर सकते। यहां तक ​​कि अगर आपने टेम्प्लेट का उपयोग नहीं किया है, लेकिन कुछ ठोस प्रकार, तो यह समस्या को कहीं और ले जाया जाएगा, क्योंकि आपके कोड के पाठक को उक्त प्रकार की घोषणा के बारे में जानना होगा।

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

के बारे में var(चूंकि आपने स्पष्ट रूप से इसका उल्लेख किया है), उपयोग करने के लिए सी # समुदाय में एक विशाल सहमति भी है । इसके उपयोग के खिलाफ तर्क आम तौर पर पतन पर निर्मित होते हैं ।var


1
मुझे लगता है कि बिंदु यह था कि ऑटो के साथ आपको पता नहीं है कि आपने आगे क्या रखा है ... क्या यह आपका कोड विशिष्ट "कुछ" है या क्या यह आपके डेटा ऑब्जेक्ट को प्राप्त करने के लिए डेटा टाइपिंग से संबंधित है जो कि "कुछ" विधि है
माइकल शॉ

1
@Ptolemy और मेरी बात यह है: अन्य दो कोडों में आप यह भी नहीं जानते (आम तौर पर) कि आगे क्या रखा जाए: Tउपयोगकर्ता के लिए अपारदर्शी है auto। अभी तक एक ठीक है और दूसरे को माना जाता है ?! इसका कोई मतलब नहीं है। ओपी के मामले Tमें, एक मनमाना प्रकार के लिए एक स्टैंड-इन है। वास्तविक कोड में, यह टेम्प्लेट (for typename std::vector<T>::iterator…)या क्लास इंटरफ़ेस का उपयोग हो सकता है। दोनों मामलों में, वास्तविक प्रकार उपयोगकर्ता से छिपा हुआ है, और फिर भी हम नियमित रूप से बिना मुद्दों के ऐसे कोड लिखते हैं।
कोनराड रुडोल्फ

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

1
@Ptolemy ये सभी तर्क उपयोग करते समय बिलकुल सही हैं auto। यह देखना तुच्छ है कि xसंदर्भ से कौन-कौन सी कार्रवाइयाँ समर्थन करती हैं। वास्तव में, प्रकार आपको कोई अतिरिक्त जानकारी नहीं देता है : किसी भी मामले में आपको समर्थित कार्यों के सेट को बताने के लिए आपको कुछ माध्यमिक (IDE, प्रलेखन, ज्ञान / स्मृति) की आवश्यकता होती है।
कोनराड रुडोल्फ

1
@Ptolemy केवल यह सच है यदि आप अत्यधिक जटिल स्थिति में हैं कि आप नहीं जानते कि क्या beginरिटर्न है, लेकिन आप जानते हैं कि क्या std::vector<>::iteratorहै। और आपको एक खराब प्रोग्रामिंग टूल का उपयोग करने की आवश्यकता है जो आपको यह जानकारी तुच्छ रूप से नहीं दे सकता है। यह अत्यधिक जटिल है। हकीकत में, आप या तो beginऔर iteratorन तो दोनों को जानते हैं , और आपको एक आईडीई या संपादक का उपयोग करना चाहिए जो आपको प्रासंगिक जानकारी आसानी से उपलब्ध करा सकता है। हर आधुनिक आईडीई और प्रोग्रामिंग एडिटर ऐसा कर सकते हैं।
कोनराड रुडोल्फ

11

समर्थक

तुम्हारा कोड :

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

टेम्पलेट निर्भर नाम के कारण, संकलन नहीं हो रहा है।

यह सही सिंटैक्स है:

for( typename std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

अब देखिए कि टाइप डिक्लेरेशन कब तक है। यह बताता है कि autoकीवर्ड क्यों पेश किया गया था। इस :

for( auto it = x.begin(); it != x.end(); i++)

अधिक संक्षिप्त है। तो, यह एक समर्थक है।


CON

आपको थोड़ा सावधान रहना होगा। कीवर्ड के साथ auto, आपको वह प्रकार मिलेगा जो आपने घोषित किया था।

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

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto it : v )
{
  ++ it;   // ops modifying copies of vector's elements
}

बनाम

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto & it : v )   // mind the reference
{
  ++ it;   // ok, vector's elements modified
}

निष्कर्ष निकालने के लिए: हाँ, आपको यह करना चाहिए, लेकिन इसका उपयोग नहीं करना चाहिए। कुछ लोग इसका बहुत अधिक उपयोग करते हैं, और हर जगह ऑटो लगाते हैं, जैसे कि अगले उदाहरण में:

auto i = 0;

बनाम

int i = 0;

auto i = 0। दोषी। मैं ऐसा करता हूँ। लेकिन ऐसा इसलिए है क्योंकि मुझे पता है कि 0यह एक प्रकार का शब्द है int। (और एक अष्टक स्थिर ;-))
लॉरेंट ला रिज़्ज़ा

6

हाँ तुम्हें करना चाहिए! autoप्रकार को मिटाता नहीं है; यहां तक ​​कि अगर आप "नहीं जानते" क्या x.begin()है, तो कंपाइलर जानता है और यदि आप गलत तरीके से उपयोग करने का प्रयास करते हैं तो एक त्रुटि की रिपोर्ट करेगा। इसके अलावा, mapए के साथ अनुकरण करने के लिए यह असामान्य नहीं है vector<pair<Key,Value>>, इसलिए उपयोग करने वाला कोड autoदोनों शब्दकोश अभ्यावेदन के लिए काम करेगा।


4

हां, आपको autoएक डिफ़ॉल्ट नियम के रूप में उपयोग करना चाहिए । इस प्रकार को स्पष्ट रूप से निर्दिष्ट करने पर इसके कच्चे लाभ हैं:

  • यह आपको उन चीजों को टाइप करने के लिए नहीं बनाता है जो कंपाइलर पहले से जानते हैं
  • यह रिटर्न वैल्यू प्रकारों में किसी भी परिवर्तन के साथ "अनुसरण" के प्रकार बनाता है।
  • ऐसा करने पर, यह स्थानीय रूपांतरणों में निहित रूपांतरण और स्लाइसिंग के मौन परिचय को रोकता है।
  • यह टेम्पलेट्स में कुछ स्पष्ट प्रकार की गणनाओं की आवश्यकता को हटाता है।
  • यह लंबे नामों के साथ रिटर्न प्रकार के नामकरण की आवश्यकता को हटाता है। (जिन्हें आप कंपाइलर डायग्नोस्टिक्स से कॉपी-पेस्ट करते हैं)

यह वह जगह है जहाँ आपके पास एक विकल्प है। ऐसे मामले भी हैं जहां आपके पास कोई विकल्प नहीं है:

  • यह एक लंबोदर के प्रकार की तरह, अव्यवहारिक प्रकारों के चर की घोषणा करता है।

बशर्ते कि आपको ठीक-ठीक पता हो कि autoइसका क्या नुकसान है।

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