C ++ 11 में कौन से C ++ मुहावरों को चित्रित किया गया है?


192

नए मानक के साथ, चीजों को करने के नए तरीके हैं, और कई पुराने तरीकों की तुलना में अच्छे हैं, लेकिन पुराना तरीका अभी भी ठीक है। यह भी स्पष्ट है कि नया मानक आधिकारिक तौर पर बहुत अधिक नहीं है, पिछड़े संगतता कारणों के लिए। तो जो प्रश्न शेष है, वह है:

कोडिंग के पुराने तरीके निश्चित रूप से C ++ 11 शैलियों से नीच हैं, और अब हम इसके बजाय क्या कर सकते हैं?

इसका उत्तर देने में, आप "ऑटो चर का उपयोग करें" जैसी स्पष्ट चीजों को छोड़ सकते हैं।


13
आप नहीं कर सकते का बहिष्कार मुहावरों।
पाब्बी

6
गोइंग नेटिव 2012 में हर्ब सटर की चर्चा ने इसे कवर किया:
bames53

5
निरंतर मूल्यों को लौटाना अब प्रोत्साहित नहीं करता है। जाहिर auto_ptrहै, भी पदावनत है।
केरेक एसबी

27
बेशक आप कर सकते हैं, पबबी। C ++ टेम्प्लेट का आविष्कार करने से पहले टेम्प्लेट करने के लिए मैक्रो तकनीक थी। फिर सी ++ ने उन्हें जोड़ा, और पुराने तरीके को बुरा माना गया।
एलन बलजे

7
इस प्रश्न को वास्तव में Programmers.se पर ले जाने की आवश्यकता है।
निकोल बोल

जवाबों:


173
  1. अंतिम वर्ग : C ++ 11 finalवर्ग व्युत्पत्ति को रोकने के लिए विनिर्देशक प्रदान करता है
  2. C ++ 11 लैम्ब्डा नामांकित ऑब्जेक्ट ऑब्जेक्ट (फ़ाइक्टर) कक्षाओं की आवश्यकता को काफी हद तक कम कर देता है।
  3. मूव कंस्ट्रक्टर : जिस जादुई तरीके से std::auto_ptrकाम किया जाता है, उसके लिए अब रेवले के संदर्भ के लिए प्रथम श्रेणी के समर्थन की जरूरत नहीं है।
  4. सुरक्षित बूल : यह पहले उल्लेख किया गया था। C ++ 11 के स्पष्ट परिचालक इसे बहुत ही सामान्य C ++ 03 मुहावरा मानते हैं।
  5. सिकुड़-फिट : कई सी ++ 11 एसटीएल कंटेनर एक shrink_to_fit()सदस्य फ़ंक्शन प्रदान करते हैं , जो एक अस्थायी के साथ स्वैपिंग की आवश्यकता को समाप्त करना चाहिए।
  6. अस्थाई आधार वर्ग : कुछ पुराने C ++ पुस्तकालय इसके बजाय जटिल मुहावरे का उपयोग करते हैं। चाल शब्दार्थ के साथ इसकी अब आवश्यकता नहीं है।
  7. C ++ 11 में सुरक्षित Enum Enumerations टाइप करें
  8. ढेर आवंटन पर प्रतिबंध : = deleteवाक्यविन्यास यह कहने का एक अधिक प्रत्यक्ष तरीका है कि किसी विशेष कार्यक्षमता को स्पष्ट रूप से नकार दिया जाता है। यह ढेर आवंटन (यानी, =deleteसदस्य के लिए operator new), प्रतियों, असाइनमेंट आदि को रोकने के लिए लागू होता है ।
  9. Typedef टेम्प्लेट की गई : उर्फ टेम्पलेट्स सी ++ 11 में सरल टेम्प्लेट की typedefs की आवश्यकता को कम। हालांकि, जटिल प्रकार के जनरेटर को अभी भी मेटा फ़ंक्शन की आवश्यकता है।
  10. कुछ संख्यात्मक संकलन-समय की गणना, जैसे कि फिबोनाकी को सामान्यीकृत स्थिर अभिव्यक्तियों का उपयोग करके आसानी से बदला जा सकता है
  11. result_of: वर्ग टेम्पलेट के उपयोग के result_ofसाथ प्रतिस्थापित किया जाना चाहिए decltype। मुझे लगता है कि यह उपलब्ध होने पर result_ofउपयोग करता decltypeहै।
  12. इन-क्लास सदस्य इनिशियलाइज़र, डिफ़ॉल्ट मान वाले गैर-स्टैटिक सदस्यों के डिफ़ॉल्ट इनिशियलाइज़ेशन के लिए टाइपिंग को सहेजते हैं।
  13. नए C ++ 11 कोड के NULLरूप में नए सिरे से परिभाषित किया जाना चाहिए nullptr, लेकिन यह जानने के लिए STL की बात देखें कि उन्होंने इसके खिलाफ फैसला क्यों किया।
  14. अभिव्यक्ति टेम्पलेट कट्टरपंथी C ++ 11 में अनुगामी रिटर्न प्रकार फ़ंक्शन सिंटैक्स के लिए खुश हैं । कोई और अधिक 30-लाइन लंबी वापसी प्रकार!

मुझे लगता है कि मैं वहाँ रुक जाऊँगा!


विस्तृत सामान के लिए धन्यवाद!
एलन बलजे

7
महान जवाब है, लेकिन मैं result_ofसूची से हड़ताल करेंगे । typenameइससे पहले कि बोझिल होने के बावजूद , मुझे लगता है कि typename result_of<F(Args...)::typeकभी-कभी पढ़ने में आसान हो सकता है decltype(std::declval<F>()(std::declval<Args>()...), और वर्किंग पेपर में N3436 की स्वीकृति के साथ वे दोनों SFINAE के लिए काम करते हैं (जो decltypeकि फायदा result_ofनहीं हुआ करता था)
जोनाथन वेक

14 के बारे में) मैं अभी भी रो रहा हूं कि मुझे दो बार एक ही कोड लिखने के लिए मैक्रोज़ का उपयोग करना है - एक बार फंक्शन बॉडी के लिए और एक बार डिक्लेप्ट के लिए () स्टेटमेंट ...

2
मैं यह नोट करना चाहूंगा कि यह विषय इस Microsoft पृष्ठ से "सामान्य जानकारी के लिए" लेख के रूप में C ++ भाषा में एक सामान्य परिचय से जुड़ा हुआ है , लेकिन यह विषय अत्यधिक विशिष्ट है! मैं सुझाव दे सकता हूं कि एक संक्षिप्त "यह विषय C ++ नौसिखियों के लिए नहीं है!" सलाह विषय या इस उत्तर की शुरुआत में शामिल किया जाना चाहिए?
आकिनी

पुन: 12: "इन-क्लास मेंबर इनिशियलाइज़ेशन" - यह नया मुहावरा है, न कि मुहावरेदार मुहावरा, यह नहीं है? शायद वाक्य आदेश स्विच करें? पुन: 2: फ़ंक्शंस बहुत उपयोगी होते हैं जब आप ऑब्जेक्ट्स (विशेष रूप से टेम्प्लेट पैरामीटर) के बजाय आसपास के प्रकारों को पास करना चाहते हैं। इसलिए यह केवल उन फंक्शनलर्स के कुछ उपयोग हैं जिन्हें अपग्रेड किया गया है।
ईनपोकलम 20

66

एक समय में यह तर्क दिया गया था कि किसी को constकेवल मूल्य के बजाय मूल्य से लौटना चाहिए :

const A foo();
^^^^^

यह सी ++ 98/03 में ज्यादातर हानिरहित था, और कुछ कीड़े भी पकड़े हो सकते हैं जो इस तरह दिखते हैं:

foo() = a;

लेकिन लौटने से constC ++ 11 में contraindicated है क्योंकि यह स्थानांतरित शब्दार्थ को रोकता है:

A a = foo();  // foo will copy into a instead of move into it

तो बस आराम करो और कोड:

A foo();  // return by non-const value

9
रोके जाने योग्य गलतियों को हालांकि कार्यों के लिए संदर्भ क्वालिफायर का उपयोग करके पकड़ा जा सकता है। जैसे कि उपरोक्त मामले में A& operator=(A o)&इसके बजाय परिभाषित करना A& operator=(A o)। ये मूर्खतापूर्ण गलतियों को रोकते हैं और कक्षाओं को मूल प्रकारों की तरह व्यवहार करते हैं और गतिरोध को नहीं रोकते हैं।
जो

61

जैसे ही आप त्याग कर सकते हैं 0और NULLइसके पक्ष में हैं nullptr, ऐसा करें!

गैर-जेनेरिक कोड में 0या NULLका उपयोग इतनी बड़ी बात नहीं है। लेकिन जैसे ही आप जेनेरिक कोड में अशक्त सूचक स्थिरांक के आसपास से गुजरना शुरू करते हैं, स्थिति जल्दी बदल जाती है। जब आप 0एक के template<class T> func(T) Tरूप में कटौती करने के लिए पास हो जाता है intऔर एक शून्य सूचक स्थिर के रूप में नहीं। और यह उसके बाद एक अशक्त पॉइंटर निरंतर में परिवर्तित नहीं किया जा सकता है। यह उन समस्याओं का एक दल में समाहित करता है जो केवल ब्रह्माण्ड का उपयोग करने पर मौजूद नहीं हैं nullptr

C ++ 11 अपवित्र नहीं है 0और NULLअशक्त सूचक स्थिरांक के रूप में है। लेकिन आपको कोड करना चाहिए जैसे कि यह किया।


घोषणापत्र (nullptr) क्या है?

4
@GrapschKnutsch: यह है std::nullptr_t
बजे हावर्ड हिनान्ट

सुझाएँ इस rephrased जा के रूप में मुहावरा नई परिपाटी के बजाय पदावनत को अपनाने के लिए (उदाहरण के लिए "के उपयोग 0या NULLअशक्त संकेत के लिए")।
ईनपोक्लुम

38

सुरक्षित bool मुहावराexplicit operator bool()

प्राइवेट कॉपी कंस्ट्रक्टर (बूस्ट :: नॉनकैपेबल) → X(const X&) = delete

निजी विध्वंसक और आभासी विरासत के साथ अंतिम वर्ग का अनुकरणclass X final


अच्छे और संक्षिप्त उदाहरण, जिनमें से एक शब्द "मुहावरा" भी है। अच्छी तरह से
सेबस्टियन मच

2
वाह, मैंने पहले कभी 'सुरक्षित बूल मुहावरा' नहीं देखा, यह काफी घृणित लग रहा है! मुझे आशा है कि मुझे प्री-सी ++ 11 कोड में कभी भी इसकी आवश्यकता नहीं है ...
9

24

चीजों में से एक जो आपको बस C ++ 11 में बुनियादी एल्गोरिदम लिखने से बचती है, मानक पुस्तकालय द्वारा प्रदान किए गए एल्गोरिदम के संयोजन में लैम्ब्डा की उपलब्धता है।

मैं अब उन का उपयोग कर रहा हूं और यह अविश्वसनीय है कि आप कितनी बार बताते हैं कि आप फिर से लानत लिखने के लिए count_if (), for_each () या अन्य एल्गोरिदम का उपयोग करके क्या करना चाहते हैं।

एक बार जब आप पूरी C ++ 11 मानक लाइब्रेरी के साथ C ++ 11 कंपाइलर का उपयोग कर रहे हों, तो आपके पास अपना निर्माण करने के लिए मानक एल्गोरिदम का उपयोग नहीं करने के लिए अब कोई अच्छा बहाना नहीं है । लाम्बा बस इसे मार देते हैं।

क्यों?

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

मूल रूप से, मानक एल्गोरिदम के साथ बनाए गए एल्गोरिदम को पढ़ना लूप के कार्यान्वयन विवरण को छिपाने वाले शब्दों के रूप में कहीं अधिक आसान है।

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


8
वास्तव में एक अच्छा बहाना है। आप Boost.Range के एल्गोरिदम का उपयोग कर रहे हैं , जो बहुत अच्छे हैं;)
निकोल बोल

10
मैं नहीं देखता कि for_eachलैंबडा लूप के लिए लैंबडा की सामग्री के साथ, लूप के लिए बराबर रेंज-आधारित से बेहतर है। कोड कमोबेश एक जैसा दिखता है, लेकिन लैम्ब्डा कुछ अतिरिक्त विराम चिह्नों का परिचय देता है। आप चीजों के समतुल्य का उपयोग कर सकते हैं जैसे boost::irangeकि इसे उन लोगों की तुलना में अधिक छोरों पर लागू करना जो स्पष्ट रूप से पुनरावृत्तियों का उपयोग करते हैं। साथ ही लूप के लिए रेंज-आधारित में अधिक लचीलापन है, इसमें आप जल्दी से बाहर निकल सकते हैं यदि आवश्यक हो (तो returnया इसके द्वारा break), जबकि for_eachआपको फेंकने की आवश्यकता होगी।
स्टीव जेसोप

5
@SteveJessop: यहां तक ​​कि, रेंज-आधारित की उपलब्धता forसामान्य it = c.begin(), const end = c.end(); it != end; ++itमुहावरे को विचलित कर देती है।
बेन वोइगट

7
@SteveJessop for_eachलूप के आधार पर एल्गोरिथ्म का एक फायदा यह है कि आप कर सकते हैं break या नहींreturn । यही है, जब आप देखते for_eachहैं कि आप तुरंत शरीर को देखे बिना जानते हैं कि ऐसी कोई चालाकी नहीं है।
bames53

5
@Klaim: विशिष्ट होना, मैं उदाहरण के लिए तुलना कर रहा हूं std::for_each(v.begin(), v.end(), [](int &i) { ++i; });साथ for (auto &i : v) { ++i; }। मैं स्वीकार करता हूं कि लचीलापन दोधारी है ( gotoबहुत लचीला है, यही समस्या है)। मुझे नहीं लगता कि कि उपयोग करने में सक्षम नहीं किया जा रहा की कमी breakमें for_eachअतिरिक्त शब्दाडंबर यह मांग करता है के लिए संस्करण क्षतिपूर्ति - के उपयोगकर्ताओं for_eachयहाँ IMO सैद्धांतिक धारणा का एक प्रकार है कि के लिए वास्तविक पठनीयता और सुविधा का त्याग कर रहे हैं for_eachहै सिद्धांत रूप में स्पष्ट और धारणात्मक सरल होते हैं। व्यवहार में यह स्पष्ट या सरल नहीं है।
स्टीव जेसोप

10

आपको swapकम बार कस्टम संस्करण लागू करने की आवश्यकता होगी । C ++ 03 में, swapमहंगी और फेंकने वाली प्रतियों से बचने के लिए एक कुशल गैर-फेंकना अक्सर आवश्यक होता है और चूंकि std::swapदो प्रतियों का उपयोग swapहोता है , इसलिए अक्सर इसे अनुकूलित करना पड़ता है। C ++ में, std::swapउपयोग करता है move, और इसलिए कुशल और गैर-फेंकने वाले चाल निर्माणकर्ताओं को लागू करने पर ध्यान केंद्रित करता है और असाइनमेंट ऑपरेटरों को स्थानांतरित करता है। चूंकि इन के लिए डिफ़ॉल्ट अक्सर ठीक होता है, इसलिए यह C ++ 03 की तुलना में बहुत कम काम होगा।

आम तौर पर यह अनुमान लगाना कठिन है कि अनुभव के माध्यम से किन मुहावरों का उपयोग किया जाएगा। हम अगले वर्ष शायद "प्रभावी C ++ 11" की उम्मीद कर सकते हैं, और "C ++ 11 कोडिंग मानक" केवल तीन वर्षों में क्योंकि आवश्यक अनुभव अभी तक नहीं है।


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

हाँ, लेकिन मूव कंस्ट्रक्टर आमतौर पर एक कस्टम स्वैप कहता है, या यह अनिवार्य रूप से समतुल्य है।
उलटा

2

मैं इसके लिए नाम नहीं जानता, लेकिन C ++ 03 कोड ने अक्सर लापता निर्माण असाइनमेंट के प्रतिस्थापन के रूप में निम्नलिखित निर्माण का उपयोग किया:

std::map<Big, Bigger> createBigMap(); // returns by value

void example ()
{
  std::map<Big, Bigger> map;

  // ... some code using map

  createBigMap().swap(map);  // cheap swap
}

इसके बाद के swapसंस्करण के साथ संयुक्त नकल के कारण किसी भी नकल से बचा गया।


1
आपके उदाहरण में स्वैप अनावश्यक है, कॉपी इलिशन mapवैसे भी रिटर्न वैल्यू का निर्माण करेगा । आपके द्वारा दिखाई जाने वाली तकनीक उपयोगी है यदि mapपहले से ही मौजूद है, बल्कि निर्माण किया जा रहा है। उदाहरण के बिना "सस्ते डिफ़ॉल्ट कंस्ट्रक्टर" टिप्पणी के बिना बेहतर होगा और उस निर्माण और स्वैप के बीच "// ..." के साथ
जोनाथन वेकली

मैंने आपके सुझाव के अनुसार इसे बदल दिया। धन्यवाद।
आंद्रेज्ज

"बड़ा" और "बड़ा" का उपयोग भ्रामक है। क्यों नहीं समझाएं कि कुंजी के आकार और मूल्य प्रकार क्या हैं?
ईनपोक्लुम

1

जब मैंने देखा कि C ++ 11 मानक का उपयोग करने वाला एक कंपाइलर अब निम्न कोड को दोष नहीं देता है:

std::vector<std::vector<int>> a;

माना जाता है कि संचालक >>, मैं नृत्य करने लगा। पहले के संस्करणों में एक करना होगा

std::vector<std::vector<int> > a;

मामलों को बदतर बनाने के लिए, यदि आपको कभी भी यह डिबग करना था, तो आप जानते हैं कि इससे निकलने वाले त्रुटि संदेश कितने भयावह हैं।

हालांकि, मुझे नहीं पता कि यह आपके लिए "स्पष्ट" था या नहीं।


1
यह सुविधा पिछले C ++ में पहले ही जोड़ दी गई थी। या कम से कम विजुअल C ++ ने इसे मानकों के अनुसार कई साल पहले चर्चा में लागू किया था।
एलन बलजे

1
@AlanBaljeu, संकलक / पुस्तकालयों में कई गैर-मानक चीजें जोड़ी जा रही हैं। C ++ 11 से पहले "ऑटो" चर घोषणा करने वाले टन संकलक थे, लेकिन तब आप यह सुनिश्चित नहीं कर सकते थे कि आपका कोड वास्तव में किसी और चीज द्वारा संकलित किया जा सकता है। सवाल मानक के बारे में था, न कि "कोई कंपाइलर था जो ऐसा कर सकता था"।
v010dya

1

मूल्य से वापसी अब कोई समस्या नहीं है। मूव सिमेंटिक्स और / या रिटर्न वैल्यू ऑप्टिमाइज़ेशन (कंपाइलर डिपेंडेंट) के साथ कोडिंग फ़ंक्शंस अधिक ओवरहेड या कॉस्ट (अधिकांश समय) के साथ स्वाभाविक हैं।


... लेकिन किस मुहावरे को हटा दिया गया है?
ईनपोक्लुम

एक मुहावरा नहीं, लेकिन यह एक अच्छा अभ्यास था जिसकी अब कोई आवश्यकता नहीं है। कंपाइलर समर्थित आरवीओ के साथ भी जो वैकल्पिक है। en.wikipedia.org/wiki/Return_value_optimization "C ++ के विकास के शुरुआती चरणों में, भाषा की अक्षमता एक समारोह से कुशलतापूर्वक एक वर्ग प्रकार की वस्तु को वापस करने के लिए एक कमजोरी माना जाता था ....." संरचनात्मक डेटा / चार बाइट्स [ 16]; }; void f (डेटा * p) {// जनरेट परिणाम सीधे * p} int main () {डेटा d; च (और घ); }
मार्टिन ए

मैं संकेत कर रहा था कि आपको अपने उत्तर को "मान से वापसी से बचने का रिवाज नहीं है, आदि आदि" के रूप में उद्धृत करना चाहिए।
ईनपोकलुम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.