C ++ 11 ऑटो कीवर्ड के साथ कितना अधिक है?


218

मैं autoजटिल टेम्प्लेटेड प्रकारों के लिए C ++ 11 मानक में उपलब्ध नए कीवर्ड का उपयोग कर रहा हूं , जो मुझे विश्वास है कि इसके लिए डिज़ाइन किया गया था। लेकिन मैं इसका उपयोग चीजों के लिए भी कर रहा हूं जैसे:

auto foo = std::make_shared<Foo>();

और अधिक संदेह के लिए:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

मैंने इस विषय पर ज्यादा चर्चा नहीं की है। ऐसा लगता है कि autoइसका उपयोग किया जा सकता है, क्योंकि एक प्रकार अक्सर प्रलेखन और पवित्रता जांच का एक रूप है। आप उपयोग करने में लाइन कहां से खींचते autoहैं और इस नई सुविधा के लिए अनुशंसित उपयोग के मामले क्या हैं?

स्पष्ट करने के लिए: मैं एक दार्शनिक राय के लिए नहीं कह रहा हूँ; मैं मानक समिति द्वारा इस खोजशब्द के अभिप्रेत उपयोग के लिए कह रहा हूँ, संभवत: टिप्पणियों के साथ कि अभिप्रेत उपयोग अभ्यास में कैसे होता है।

साइड नोट: इस सवाल को SE.Programmers पर ले जाया गया और फिर स्टैक ओवरफ्लो में वापस लाया गया। इसके बारे में चर्चा इस मेटा प्रश्न में पाई जा सकती है ।


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

15
@ हीशे, मैंने एक स्पष्टीकरण जोड़ा। यदि आप प्रश्न को आम तौर पर पढ़ते हैं, तो यह व्यक्तिपरक राय पूछ रहा है, लेकिन वास्तव में यदि आपने autoकीवर्ड का उपयोग किया है , तो आप जानते हैं कि इसका उपयोग कैसे किया जाना चाहिए । यही कारण है कि मैं इस सुविधा के लिए नया है, जो मैं पूछ रहा हूं, कि मैं इसका उपयोग कैसे करूं?
एलन ट्यूरिंग

13
मैंने इस चर्चा को पूरे स्थान पर देखा है जब C # पेश किया गया था var(जो कि एक बार लोगों को इस विचार से मिल गया कि यह गतिशील टाइपिंग नहीं है)। आप चाहें तो इस सवाल से शुरुआत कर सकते हैं और संबंधित सवालों से गुजर सकते हैं।
आर। मार्टिनो फर्नांडीस

2
@Lex: या तो कुछ कानूनी है या यह नहीं है; कानूनी रूप से व्यक्तिपरक कुछ "बुरा" कहना। यानी, auto foo = bla();"बुरा" कहना स्पष्ट रूप से एक राय है, एक तथ्य नहीं है, जो इस सवाल का जवाब देता है और एक चर्चा का जवाब देता है, जो इसे प्रोग्रामर एसई के लिए प्रासंगिक बनाता है, जो वास्तव में करीबी वोटों का संकेत देता है। /
श्रग

3
इस मामले पर हर्ब सटर दृश्य: जड़ी
बूटियों की दवा.कॉम

जवाबों:


131

मुझे लगता है कि autoजब भी पहली नजर में टाइप लिखना हो तो यह कहना मुश्किल है कि कीवर्ड का उपयोग कैसे किया जाना चाहिए , लेकिन किसी अभिव्यक्ति के दाएं हाथ का प्रकार स्पष्ट है। उदाहरण के लिए, उपयोग करना:

my_multi_type::nth_index<2>::type::key_type::composite_key_type::
    key_extractor_tuple::tail_type::head_type::result_type

boost::multi_indexभले ही आप जानते हैं कि समग्र कुंजी प्रकार प्राप्त करना है int। आप सिर्फ intइसलिए नहीं लिख सकते क्योंकि इसे भविष्य में बदला जा सकता है। मैं autoइस मामले में लिखूंगा ।

इसलिए यदि autoकीवर्ड किसी विशेष मामले में पठनीयता में सुधार करता है तो इसका उपयोग करें। आप लिख सकते हैं autoजब यह पाठक के लिए स्पष्ट है कि किस प्रकार का autoप्रतिनिधित्व करता है।

यहाँ कुछ उदाहरण हैं:

auto foo = std::make_shared<Foo>();   // obvious
auto foo = bla();                     // unclear. don't know which type `foo` has

const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
                                      // since max_size is unsigned

std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
                                      // ok, since I know that `it` has an iterator type
                                      // (don't really care which one in this context)

18
यह एक बहुत अच्छी सिफारिश की तरह नहीं लगता है। यह कितनी बार है कि आप वस्तु का प्रकार नहीं जानते हैं? (टेम्पलेट्स के बाहर, वह है।) और यदि आप नहीं जानते कि वे टाइप करते हैं, तो इसे देखें, आलसी न हों और ऑटो का उपयोग करें।
पॉल मंटा

9
@Paul: अक्सर आप केवल बार या केवल टाइप के सबसे महत्वपूर्ण भाग को जानते हैं, उदाहरण के लिए, कि यह एक पुनरावृत्ति है, लेकिन आप नहीं जानते हैं और परवाह नहीं है कि क्या यह वैक्टर का एक इटर्नेटर है या लिंक्ड का इटरेटर सूची; उन मामलों में, आप वास्तव में समय और स्क्रीन स्थान खर्च करने की कोशिश नहीं करना चाहते हैं ताकि यह पता लगाया जा सके कि नीचे के प्रकार कैसे लिखें।
रेयान

45
C ++ डाइहार्ड्स इसे पसंद करेंगे या नहीं, C ++ 0x उन लोगों को आकर्षित करेगा जिन्होंने कभी C ++ का उपयोग नहीं किया होगा। और वे सभी जगह ऑटो का उपयोग करेंगे।
प्रो। फालकेन

6
@ R.MartinhoFernandes - नहीं, केवल एक चीज जो स्पष्ट है वह यह है कि आप जो भी bla() रिटर्न दे रहे हैं foo
लुइस माचुका

8
@LuisMachuca मेरा जवाब यह कहने का एक जीभ-इन-गाल तरीका था कि यह खराब चर और फ़ंक्शन नामकरण का एक पाठ्यपुस्तक उदाहरण देने के लिए बेईमानी है और टाइप इंट्रेंस पर इसकी पठनीयता की कमी को दोष देता है।
आर। मार्टिनो फर्नांडीस

62

autoहर जगह आप उपयोग कर सकते हैं - विशेष रूप से const autoताकि साइड इफेक्ट एक चिंता का कम हो। आपको स्पष्ट मामलों को छोड़कर प्रकारों के बारे में चिंता करने की ज़रूरत नहीं है, लेकिन वे अभी भी आपके लिए सांख्यिकीय रूप से सत्यापित होंगे, और आप कुछ पुनरावृत्ति से बच सकते हैं। जहां autoसंभव नहीं है, आप अभिव्यक्ति के आधार पर अनुबंधों केdecltype रूप में शब्दार्थ व्यक्त करने के लिए उपयोग कर सकते हैं । आपका कोड अलग दिखेगा, लेकिन यह एक सकारात्मक बदलाव होगा।


12
मैं विशेष रूप से कहूँगा 'कास्ट ऑटो एंड'
विक्टर सेहर

2
बेहतर उपयोग auto&&जटिल परिस्थितियों में edmundv.home.xs4all.nl/blog/2014/01/28/...
KindDragon

2
@KindDragon: यह अंगूठे का एक अच्छा नियम है, लेकिन मैं उपयोग करना पसंद करता हूं const auto&या const autoजब तक मैं स्पष्ट रूप से म्यूट या स्थानांतरित नहीं करना चाहता।
जॉन पूर्डी

" हर जगह ऑटो का उपयोग करें जो आप कर सकते हैं "। क्या इसका मतलब मुझे auto str = std::string();इसके बजाय लिखना चाहिए std::string str;?
कैलमरीस

4
सभी जगह ऑटो का उपयोग करने से आपका कोड कम पठनीय और डीबग करने में कठिन हो जाएगा क्योंकि आपको कोड पढ़ते समय खुद प्रकारों को कम करना होगा।
सबमशीन

52

आसान। इसका उपयोग तब करें जब आपको परवाह न हो कि प्रकार क्या है। उदाहरण के लिए

for (const auto & i : some_container) {
   ...

यहाँ पर मुझे ध्यान है कि iकंटेनर में जो कुछ भी है।

यह थोड़ा टाइप्डिफ्स जैसा है।

typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;

यहाँ, मुझे परवाह नहीं है कि क्या hऔर wकर रहे हैं तैरता या डबल्स, वे कर रहे हैं केवल कि जो कुछ भी प्रकार ऊंचाई और वजन को व्यक्त करने के लिए उपयुक्त है

या विचार करें

for (auto i = some_container .begin (); ...

यहाँ मुझे इस बात की परवाह है कि यह एक उपयुक्त पुनरावृत्ति है, समर्थन करते हुए operator++(), यह इस संबंध में बतख टाइपिंग की तरह है।

इसके अलावा लैम्ब्डा के प्रकार को वर्तनी नहीं दी जा सकती है, इसलिए auto f = []...यह अच्छी शैली है। विकल्प के लिए कास्टिंग है, std::functionलेकिन यह ओवरहेड के साथ आता है।

मैं वास्तव में "दुरुपयोग" की कल्पना नहीं कर सकता auto। निकटतम मैं कल्पना कर सकता हूं कि आप अपने आप को कुछ महत्वपूर्ण प्रकारों में एक स्पष्ट रूपांतरण से वंचित कर रहे हैं - लेकिन आप इसके autoलिए उपयोग नहीं करेंगे , आप वांछित प्रकार की एक वस्तु का निर्माण करेंगे।

यदि आप साइड इफेक्ट्स को शुरू किए बिना अपने कोड में कुछ अतिरेक को हटा सकते हैं, तो ऐसा करना अच्छा होना चाहिए।

Counterexamples (किसी और के उत्तर से उधार लिया गया):

auto i = SomeClass();
for (auto x = make_unsigned (y); ...)

यहाँ हम ध्यान रखते हैं कि प्रकार क्या है, इसलिए हमें लिखना चाहिए Someclass i;औरfor(unsigned x = y;...


1
उम। इतना आसान नही। यह संकलित करता है और चलाता है, और आपने अपने आप को पैर में गोली मार ली है यदि आइटम nontrivial ऑब्जेक्ट हैं - आपका पुनरावृति पुनरावृत्ति के हर चरण पर कॉपी कंस्ट्रक्टर और विध्वंसक को कॉल करता है। यदि आप रेंज-आधारित पुनरावृत्ति में ऑटो का आँख बंद करके उपयोग करने जा रहे हैं, तो यह "ऑटो (आइटम: some_container)" के बजाय "(कास्ट ऑटो और आइटम: some_container)" होना चाहिए।
डॉन हैच

2
हमेशा नहीं, लेकिन ठीक है आप शायद संदर्भ चाहते हैं। तो क्या? इससे कोई लेना- देना नहीं है auto
स्पै्रक

मैं वास्तव में आपकी पिछली टिप्पणी को नहीं समझता। मैंने यह समझाने की कोशिश की कि आपकी रणनीति मुझे बहुत अच्छी क्यों नहीं लगती है और मैं इसे क्यों नीचा दिखा रहा हूं।
डॉन हैच

5
मैं यह कह रहा हूं कि आप संदर्भ का उपयोग करते हैं या नहीं कि आप ऑटो का उपयोग करते हैं या नहीं। मैं इसे संदर्भ जोड़ने के लिए संपादित करूंगा क्योंकि आमतौर पर यह वही होता है जो कोई भी करना चाहता है, लेकिन यह विषय पर पूरी तरह से अप्रासंगिक है।
स्पै्रक

43

इसका लाभ उठाएं। autoकहीं भी उपयोग करें यह लेखन कोड को आसान बनाता है।

किसी भी भाषा में हर नई सुविधा कम से कम कुछ प्रकार के प्रोग्रामर द्वारा अति प्रयोग में आने वाली है। यह केवल कुछ अनुभवी प्रोग्रामर (नॉब्स नहीं) द्वारा उदारवादी अति प्रयोग के माध्यम से है कि बाकी अनुभवी प्रोग्रामर उचित उपयोग की सीमाओं को सीखते हैं। अत्यधिक अति प्रयोग आमतौर पर बुरा है, लेकिन अच्छा हो सकता है क्योंकि इस तरह के अति प्रयोग से सुविधा में सुधार हो सकता है या इसे बदलने के लिए एक बेहतर सुविधा हो सकती है।

लेकिन अगर मैं कुछ लाइनों की तरह कोड के साथ काम कर रहा था

auto foo = bla();

जहाँ प्रकार शून्य बार इंगित किया गया है, मैं उन पंक्तियों को शामिल करने के लिए बदलना चाह सकता हूँ। पहला उदाहरण महान है क्योंकि एक बार टाइप किया गया है, और autoहमें दो बार गंदे टेम्पर्ड टाइप लिखने से बचाता है। C ++++ के लिए हुर्रे। लेकिन स्पष्ट रूप से शून्य बार दिखा रहा है, अगर यह आसानी से पास की रेखा में दिखाई नहीं देता है, तो मुझे कम से कम C ++ और इसके तत्काल समर्थकों में घबराहट होती है। अधिक अमूर्तता, बहुरूपता और उदारता के साथ उच्च स्तर पर काम करने के लिए डिज़ाइन की गई अन्य भाषाओं के लिए, यह ठीक है।


38

पर सी ++ और परे 2012 में पूछो हमें कुछ भी पैनल, वहाँ एक था आंद्रेई Alexandrescu, स्कॉट Meyers और हर्ब Sutter के बीच शानदार विनिमय जब उपयोग करने के लिए और का उपयोग नहीं के बारे में बातauto । 4 मिनट की चर्चा के लिए 25:03 मिनट पर जाएं। सभी तीन स्पीकर उत्कृष्ट बिंदु देते हैं जिन्हें ध्यान में रखना चाहिए कि कब उपयोग करें auto

मैं लोगों को अपने स्वयं के निष्कर्ष पर आने के लिए प्रोत्साहित करता हूं, लेकिन जब तक मुझे हर जगह उपयोग नहीं करना हैauto :

  1. इससे पठनीयता को ठेस पहुंचती है
  2. स्वचालित प्रकार रूपांतरण के बारे में चिंता है (जैसे निर्माणकर्ताओं, असाइनमेंट, टेम्पलेट मध्यवर्ती प्रकार, पूर्णांक चौड़ाई के बीच अंतर्निहित रूपांतरण)

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

हर्ब ने क्या कहा, "यदि आप X, Y और Z का उपयोग नहीं कर रहे हैं, तो इसे देखें auto। जानें कि X, Y और Z क्या हैं और आगे जाकर autoहर जगह उपयोग करें ।"


4
संभवतः "लगभग हमेशा ऑटो" से जुड़ने के लायक भी है - जड़ी बूटियों का डाट काम ।/2013/08/12/…
Rob Starling

37

हां, इसे पठनीयता के नुकसान के लिए इस्तेमाल किया जा सकता है। मैं इसका उपयोग संदर्भों में करने का सुझाव देता हूं जहां सटीक प्रकार लंबे, या अप्राप्य हैं, या पठनीयता के लिए महत्वपूर्ण नहीं हैं, और चर अल्पकालिक हैं। उदाहरण के लिए, इट्रेटर प्रकार आमतौर पर लंबा होता है और महत्वपूर्ण नहीं autoहोता है , इसलिए काम करेगा:

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

auto यहाँ पठनीयता को चोट नहीं पहुँचाती है।

एक अन्य उदाहरण पार्सर नियम प्रकार है, जो लंबा और जटिल हो सकता है। की तुलना करें:

   auto spaces = space & space & space;

साथ में

r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces = 
   space & space & space;

दूसरी ओर, जब प्रकार ज्ञात होता है और सरल होता है, तो यह स्पष्ट रूप से कहा जाए तो बहुत बेहतर है:

int i = foo();

बजाय

auto i = foo();

2
बेशक, भाषा में लूप के लिए रेंज-आधारित होना आपके पहले उदाहरण को कम रोमांचक बनाता है। 8v)
फ्रेड लार्सन

@ पसंदीदा: प्रकार अभी भी बोझिल हो सकता है (मैं साहचर्य कंटेनरों सोच रहा हूँ)
Matthieu M.

3
@Fred: किसी भी समय आपकी सीमाएं नहीं हैं begin()और end(), या आपके चरण का आकार एक के अलावा कुछ भी है, या आप कंटेनर को संशोधित कर रहे हैं जैसे ही आप लूप करते हैं, बयान के लिए सीमा-आधारित आपकी मदद नहीं करेगा।
डेनिस ज़िकेफोज़

6
@geotavros: और r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&>करता है?
डेनिस ज़िकफ़ॉस जू

7
@geotavros: या आप देख सकते हैं कि प्रकार क्या spaceहै, और उसके लिए खोज करें। यह किसी भी तरह से अधिक उपयोगी जानकारी है ... आखिरकार, मुद्दा यह नहीं है "यह नया चर किस प्रकार का है" बल्कि "क्या space & space & spaceमतलब है?" अभिव्यक्ति का वास्तविक प्रकार सिर्फ शोर है।
डेनिस ज़िकेफोसे

19

auto अभिव्यक्ति टेम्पलेट्स के साथ संयोजन में बहुत खतरनाक हो सकता है जो कि एलजेन या ओपनसीवी जैसे रैखिक बीजगणित पुस्तकालयों द्वारा बहुत अधिक उपयोग किया जाता है।

auto A = Matrix(...);
auto B = Matrix(...);
auto C = A * B; // C is not a matrix. It is a matrix EXPRESSION.
cout << C; // The expression is evaluated and gives the expected result.
... // <code modifying A or B>
cout << C; // The expression is evaluated AGAIN and gives a DIFFERENT result.

इस प्रकार की गलतियों के कारण होने वाले कीड़े डिबग के लिए एक प्रमुख दर्द हैं। एक संभावित उपाय स्पष्ट रूप से अपेक्षित प्रकार के परिणाम को डालना है यदि आप बाएं से दाएं घोषित शैली के लिए ऑटो का उपयोग करने में जहन्नुम हैं।

auto C = Matrix(A * B); // The expression is now evaluated immediately.

1
ऐसा लगता है कि अजीब व्यवहार के साथ शुरू होता है। यदि मैं दो मेट्रिसेस को गुणा कर रहा हूं, भले ही ऑपरेशन आलसी हो, मैं इसकी पुनर्मूल्यांकन की उम्मीद नहीं करूंगा, मैं उम्मीद करूंगा कि प्रारंभिक मूल्यांकन के बाद इसकी मूल्यांकन स्थिति बनाए रख सके। यदि आप मूल मापदंडों को संशोधित किए बिना मापदंडों को बदलना चाहते हैं, तो क्या आप वैसे भी अभिव्यक्ति का पुनर्निर्माण नहीं करेंगे? या क्या यह स्ट्रीमिंग-प्रोसेसिंग प्रकार की स्थिति के लिए डिज़ाइन किया गया है, जहां मूल पैरामीटर लगातार बदल रहे हैं लेकिन प्रक्रिया समान है?
JAB

1
या नहीं, A*Bअभिव्यक्ति एक में कॉपी किया जाता है autoचर या कुछ और, व्यवहार आपके द्वारा बताई गई अभी भी मौजूद है।
xtofl

उपयोग करने से कोई बग उत्पन्न नहीं होता है auto
जिम बाल्टर

@JAB: यह सरलीकरण और संचालन के बीच तालमेल का समर्थन करने के लिए डिज़ाइन किया गया है, उदाहरण के diag(A * B)लिए ऑफ-विकर्ण तत्वों की गणना करने वाले चक्रों को बर्बाद करने की आवश्यकता नहीं है।
बेन वोइगट

मैंने 'for (auto o: vecContainer)' जैसे कोड को भी देखा है, जहाँ 'o' एक भारी वस्तु थी जो हर बार कॉपी हो जाती है। मेरी सिफारिश इसका उपयोग करने के लिए होगी कि यह मूल रूप से क्या इरादा था, यह टेम्पलेट (कठिन कटौती दिशानिर्देशों के साथ) और श्रमसाध्य टाइपडेफ का है। फिर भी आपको ऑटो और ऑटो और के बीच सावधान और अलग रहना होगा।
Gast128

10

मैं autowihout प्रतिबंध का उपयोग करता हूं और किसी भी समस्या का सामना नहीं करता। मैं भी कभी-कभी इसे सरल प्रकारों के लिए उपयोग करना समाप्त करता हूं int। यह मेरे लिए c ++ को उच्च स्तरीय भाषा बनाता है, और अजगर की तरह c ++ में चर घोषित करने की अनुमति देता है। अजगर कोड लिखने के बाद, मैं भी कभी-कभी उदाहरण लिखता हूं

auto i = MyClass();

के बजाय

MyClass i;

यह एक ऐसा मामला है जहां मैं कहूंगा कि यह autoकीवर्ड का दुरुपयोग है ।

अक्सर मुझे कोई आपत्ति नहीं है कि वस्तु का सटीक प्रकार क्या है, मैं इसकी तन्मयता में अधिक दिलचस्पी रखता हूं, और जैसा कि फ़ंक्शन नाम आमतौर पर उन वस्तुओं के बारे में कुछ कहते हैं, जो उन्हें वापस autoनहीं आती हैं: चोट नहीं लगती है: उदाहरण के लिए auto s = mycollection.size(), मैं अनुमान लगा सकता हूं कि यह sहोगा एक प्रकार का पूर्णांक, और दुर्लभ मामले में जहां मैं सटीक प्रकार के बारे में परवाह करता हूं, तो फ़ंक्शन प्रोटोटाइप की जांच करते हैं तब (मेरा मतलब है, मुझे इस बात की जांच करना पसंद है कि मुझे जानकारी की आवश्यकता है, बजाय प्राथमिकता के जब कोड लिखा जाता है, तो बस मामले में यह किसी दिन उपयोगी होगा, जैसा कि int_type s = mycollection.size())।

इस उदाहरण को स्वीकृत उत्तर से संबंधित है:

for ( auto x = max_size; x > 0; --x )

मेरे कोड में मैं अभी भी autoइस मामले में उपयोग करता हूं , और अगर मैं xअहस्ताक्षरित होना चाहता हूं , तो मैं एक उपयोगिता फ़ंक्शन का उपयोग करता हूं, नाम का कहना है make_unsigned, जो स्पष्ट रूप से मेरी चिंताओं को व्यक्त करता है:

for ( auto x = make_unsigned(max_size); x > 0; --x )

अस्वीकरण: मैं सिर्फ अपने उपयोग का वर्णन करता हूं , मैं सलाह देने के लिए सक्षम नहीं हूं!


1
@ChristianRau: व्यंग्यात्मक नहीं था। ध्यान दें कि मैंने उपयोग की अनुशंसा नहीं की थी auto i = MyClass()
रफक

3
फॉलो-अप: देखें: हर्बटुकटर.कॉम 2013 / 06 / 13/… । उदाहरण के as_unsignedलिए, वहां या यहां तक ​​कि उपयोग की सिफारिश की जाती है auto w = widget{};
रफक

3

C ++ प्रोग्राम के साथ एक बड़ी समस्या यह है कि यह आपको अनइंस्टॉल किए गए चर का उपयोग करने की अनुमति देता है । यह हमें गैर-निर्धारक कार्यक्रम व्यवहार की ओर ले जाता है। यह ध्यान दिया जाना चाहिए कि आधुनिक संकलक अब उचित / संदेश चेतावनी संदेश फेंकते हैं यदि प्रोग्राम टायर इसका उपयोग करने के लिए।

इसे समझने के लिए, नीचे c ++ प्रोग्राम पर विचार करें:

int main() {
    int x;
    int y = 0;
    y += x;
}

अगर मैं आधुनिक संकलक (जीसीसी) का उपयोग करके इस कार्यक्रम को संकलित करता हूं, तो यह चेतावनी देता है। यदि हम वास्तविक जटिल उत्पादन कोड के साथ काम कर रहे हैं तो ऐसी चेतावनी बहुत स्पष्ट नहीं हो सकती है।

main.cpp: फ़ंक्शन में 'int main ()':

main.cpp: 4: 8: चेतावनी : इस कार्य में 'x' का उपयोग अनइंस्टाल्यूट किया जाता है [-Wuninitialized]

y + = x;

    ^

================================================== =============================== अब अगर हम अपने प्रोग्राम को बदलते हैं जो ऑटो का उपयोग करता है , तो संकलन हमें निम्नलिखित मिलता है:

int main() {
    auto x;
    auto y = 0;
    y += x;
}

main.cpp: फ़ंक्शन में 'int main ()':

main.cpp: 2: 10: error : 'ऑटो x' की घोषणा में कोई आरंभिक नहीं है

 auto x;

      ^

ऑटो के साथ, असिंचित चर का उपयोग करना संभव नहीं है। यह प्रमुख लाभ है जो हमें (मुफ्त में) मिल सकता है, अगर हम ऑटो का उपयोग शुरू करते हैं ।

इस अवधारणा और अन्य महान महान आधुनिक C ++ अवधारणा को Cpp के विशेषज्ञ हर्ब शटर ने अपनी CppCon14 वार्ता में समझाया है :

मूल तथ्यों को पुनः देखो! आधुनिक सी ++ शैली की अनिवार्यता


2
हाँ। और उस प्रकार को निर्दिष्ट करने के लिए जिसे आप 0i, 0u, 0l, 0ul, 0.0f, 0.0, या यहां तक ​​कि int (), अहस्ताक्षरित (), डबल (), आदि के रूप में प्रारंभ कर सकते हैं
रॉबिन्सन

6
यह तर्क हास्यास्पद है। आप कह रहे हैं "आप कंपाइलर को नहीं भूल सकते क्योंकि आपको कंपाइलर की त्रुटि मिलेगी", लेकिन इसका उपयोग करने के लिए आपको याद रखना होगा auto
ऑर्बिट

1
@LightnessRacesinOrbit: मुझे एहसास हुआ (सीखा) हर्ब सटर की बात से। मैंने इसे जड़ी-बूटी की बातों से तार्किक / व्यावहारिक सलाह दी, इसलिए समुदाय के साथ साझा करने के लिए सोचा।
मंतोष कुमार

2
मुझे नहीं लगता कि यह ऑटो का उपयोग करने के लिए अच्छी प्रेरणा है। बस अपने संकलक के चेतावनी ध्वज को अनइंस्टॉल किए गए चर के उपयोग के लिए चालू करें और सभी चेतावनियों को संबोधित करें। यह कहना है कि आपको उपयोग नहीं करना चाहिए auto- लेकिन आपको इस मुद्दे को समाप्त करने की आवश्यकता नहीं है।
ईनपोकलम

2

एक खतरा मैंने नोट किया है संदर्भ के संदर्भ में। जैसे

MyBigObject& ref_to_big_object= big_object;
auto another_ref = ref_to_big_object; // ?

समस्या एक और है_ वास्तव में इस संदर्भ में एक संदर्भ नहीं है क्योंकि यह MyBigObject के बजाय MyBigObject है। आप इसे महसूस किए बिना किसी बड़ी वस्तु की नकल करते हैं।

यदि आपको एक ऐसी विधि से सीधे संदर्भ मिल रहा है जो आप सोच भी नहीं सकते कि यह वास्तव में क्या है।

auto another_ref = function_returning_ref_to_big_object();

आपको "ऑटो और" या "कास्ट ऑटो" की आवश्यकता होगी

MyBigObject& ref_to_big_object= big_object;
auto& another_ref = ref_to_big_object;
const auto& yet_another_ref = function_returning_ref_to_big_object();

1

उपयोग करें autoजहाँ यह समझ में आता है कि किस प्रकार का अनुमान लगाया जा सकता है। यदि आपके पास कुछ ऐसा है जो आपको पता है कि एक पूर्णांक है, या आपको पता है कि यह एक स्ट्रिंग है, तो int / std :: string आदि का उपयोग करें। मैं किसी भाषा की सुविधा को "अति प्रयोग" करने के बारे में चिंता नहीं करूंगा जब तक कि यह हास्यास्पदता की स्थिति में न आए, या कोड को बाधित करता है।

वैसे भी मेरी राय यही है।


4
"जहां यह समझ में आता है ..." मुश्किल हिस्सा है। प्रोग्रामर कोडिंग के विवरण में फंस सकते हैं, वे किसी भी चीज को खो देते हैं जो विशेष रूप से भविष्य के रखरखाव में अन्य प्रोग्रामर के लिए समझ में आता है।
डैरेन डब्ल्यू

यह सच है, हालाँकि मुझे लगता है कि यह बताना बहुत आसान है जब यह अस्पष्ट है। जब संदेह में, एक टिप्पणी का उपयोग करें!
LainIwakura

1
यह एक प्रकार का उपयोग करने के लिए समझ में नहीं आएगा?
मिखाइल

कुछ डेवलपर्स कहते हैं कि प्रकार हमेशा बांझ होना चाहिए !
अराफंगियन

एक टिप्पणी का उपयोग करें ...... या बस प्रकार का उपयोग करें और कोई टिप्पणी की आवश्यकता नहीं है?
user997112

1

autoकीवर्ड का उपयोग केवल स्थानीय चर के लिए किया जा सकता है, न कि तर्कों या वर्ग / संरचना सदस्यों के लिए। तो, यह सुरक्षित और व्यवहार्य है कि आप उन्हें कहीं भी उपयोग कर सकते हैं। मैं उनका भरपूर इस्तेमाल करता हूं। प्रकार को संकलन समय पर घटाया जाता है, डिबगर डिबगिंग करते समय प्रकार दिखाता है, sizeofइसे सही ढंग से रिपोर्ट करता है, decltypeसही प्रकार देगा - कोई नुकसान नहीं है। मैं अति के autoरूप में गिनती नहीं है , कभी भी!


0

टीएल; डीआर: तल पर नियम-का-अंगूठा देखें।

स्वीकार किए जाते हैं जवाब अंगूठे का निम्नलिखित नियम पता चलता है:

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

लेकिन मैं कहूंगा कि यह बहुत अधिक प्रतिबंधात्मक है। शायद ही कभी मैं प्रकारों के बारे में परवाह नहीं करता, क्योंकि विवरण के बिना मेरे बारे में जानकारी काफी है, जिससे मुझे यह पता लगाने में समय नहीं लगता है। उससे मेरा मतलब क्या है? उन उदाहरणों पर विचार करें जो कुछ उत्तरों में पॉप अप किए गए हैं:

auto x = f();

यह किसके दुरुपयोग का उदाहरण है auto? क्या यह मेरी अज्ञानता की f()वापसी प्रकार है? ठीक है, यह वास्तव में मदद कर सकता है अगर मुझे यह पता था, लेकिन - यह मेरी मुख्य चिंता नहीं है। क्या एक समस्या का बहुत अधिक है xऔर f()यह बहुत व्यर्थ है। अगर हमारे पास होता तो:

auto nugget = mine_gold();

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

तो मेरा जवाब है: autoजब भी संकलक इसे अनुमति देता है, तब तक उपयोग करें :

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

और भी:

  • autoकंक्रीट प्रकार के साथ बदलने से पहले एक सार्थक नाम देना (जिसमें पाठ्यक्रम का प्रकार शामिल नहीं है) ।

-3

मेरे एक कड़वे अनुभव autoका उपयोग इसे लंबोदर भाव के साथ कर रहा है :

auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!

वास्तव में, यहाँ के iसूचक को हल करने के लिए हल किया गया है int(*)()। यह सिर्फ एक सरल है cout, लेकिन सिर्फ कल्पना करें कि किस तरह के खराब संकलन / रनटाइम त्रुटियों के साथ इसका उपयोग किया जा सकता है template

आपको ऐसे भावों से बचना चाहिए autoऔर एक उचित returnप्रकार (या नियंत्रित decltype()) रखना चाहिए

उपरोक्त उदाहरण के लिए सही उपयोग होगा,

auto i = []() { return 0; }(); // and now i contains the result of calling the lambda  

7
आपने यह समझाने का एक भयानक काम किया कि ऑटो के साथ क्या करना है। आपने एक फंक्शन बनाया और फिर उसे प्रिंट किया ... ठीक है?
डेनिस ज़िकफ़ोज़

5
@iililind: और ऑटो के साथ क्या करना है?
आर। मार्टिनो फर्नांडिस

7
मुझे लगता है कि यह बहुत संभावना नहीं है कि कोई ()अंत में रखना चाहेगा । लैम्ब्डा वहाँ फ़ंक्शन के रूप में कार्य करने के लिए होते हैं और यहीं से फ़ंक्शन पॉइंटर रूपांतरण होता है। यदि आप इसे सीधे कॉल करना चाहते हैं, तो लैम्बडा का उपयोग क्यों करें? auto i = 0;बल्कि अच्छी तरह से काम करता है।
आर। मार्टिनो फर्नांडिस

4
क्या आप कम से कम एक परिदृश्य का वर्णन कर सकते हैं, जहां auto x = []() { /* .... whatever goes in here ... */ }()बेहतर है auto x = /* .... whatever goes in here ... */;, यानी, एक ही चीज, लंबोदर के बिना? मुझे लगता है कि बल्कि व्यर्थ है, उसी कारण auto x = 42 + y - 42व्यर्थ है।
आर। मार्टिनो फर्नांडीस

6
-1 यह ऑटो की गलती नहीं है। एक लैम्ब्डा के प्रकार को वर्तनी नहीं दी जा सकती है इसलिए ऑटो की आवश्यकता होती है , यदि आप फ़ंक्शन को कॉल करना भूल जाते हैं तो यह आपका अपना लुकआउट है! आप अन-फंक्शन पॉइंटर को सी प्रिंटफ में हैफजार्डी के रूप में डाल सकते हैं।
11
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.