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




types c++11 (10)

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

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

और इसके लिए अधिक संदिग्ध रूप से:

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

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

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

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


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

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

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

यह typedefs की तरह थोड़ा सा है।

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 उपयोग नहीं करेंगे, आप वांछित प्रकार की वस्तु का निर्माण करेंगे।

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

काउंटररेक्समल्स (किसी और के उत्तरों से उधार लिया गया):

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

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


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

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

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

auto foo = bla();

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


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

auto i = MyClass();

के बजाय

MyClass i;

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

अक्सर मुझे कोई फर्क नहीं पड़ता कि ऑब्जेक्ट का सटीक प्रकार क्या है, मुझे इसकी कार्यक्षमता में अधिक दिलचस्पी है, और फ़ंक्शन नाम आम तौर पर लौटने वाली वस्तुओं के बारे में कुछ कहते हैं, auto चोट नहीं auto s = mycollection.size() : उदाहरण के लिए 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 )

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


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

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

समस्या यह है कि another_ref वास्तव में इस मामले में एक संदर्भ नहीं है, यह 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();

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


हां, इसे पठनीयता के नुकसान के लिए अति प्रयोग किया जा सकता है। मैं उन संदर्भों में इसका उपयोग करने का सुझाव देता हूं जहां सटीक प्रकार लंबे, या अचूक हैं, या पठनीयता के लिए महत्वपूर्ण नहीं हैं, और चर अल्पकालिक हैं। उदाहरण के लिए, इटेटर प्रकार आमतौर पर लंबा होता है और यह महत्वपूर्ण नहीं है, इसलिए 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();

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

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


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


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

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

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

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

हर्ब ने क्या कहा, "यदि आप एक्स, वाई और जेड नहीं कर रहे हैं, तो auto उपयोग करें। जानें कि एक्स, वाई, और जेड क्या हैं और आगे बढ़ें और हर जगह auto उपयोग करें।"


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

स्वीकृत उत्तर अंगूठे के निम्नलिखित नियम का सुझाव देता है:

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

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

auto x = f();

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

auto nugget = mine_gold();

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

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

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

और भी:

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






auto