2015-11-13 14 views
45

में ऑटो का उपयोग जब मैं पॉइंटर प्रकार को कम करने के लिए auto का उपयोग करता हूं, तो मुझे एक अजीब घटना मिली। मेरे कोड इस तरह है:सी ++ 11

#include <iostream> 
using namespace std; 
int main() 
{ 
    int i = 100; 
    auto p1 = &i; 
    auto *p2 = &i; 

    cout << *p1 << " " << *p2 << endl; 

    return 0; 
} 

संकलन और क्रियान्वित करने के बाद, हम पा सकते हैं कि *p1 और *p2 का परिणाम एक ही है, दोनों 100 इसका मतलब यह है p1 और p2 दोनों एक सूचक वस्तु जो एक int की ओर इशारा कर रहे हैं वस्तु।

[[email protected] ~]$ ./test 
100 100 

कि इन दो बयानों जो p1 और p2 परिभाषित के बीच कोई अंतर है?

+9

बेशक, और क्या संभवतः हो सकता है? यदि पी 1 और पी 2 दोनों पॉइंटर्स नहीं थे तो आप उन्हें 'और i' के साथ प्रारंभ नहीं कर सके।हो सकता है कि आपको 'ऑटो * पी 2' 'ऑटो * पी 2' के संदर्भ में 'ऑटो * पी 2' के संदर्भ में लिखना चाहिए (और सोचें) कि यह स्पष्ट करने के लिए कि 'p2' एक सूचक प्रकार का चर है, जिसमें संकलक द्वारा स्वचालित रूप से निर्धारित किया गया है । –

+1

'ऑटो * पी 2 = init()' कच्चे सूचक प्रकार को लागू करता है। उदाहरण के लिए उपयोगी हो सकता है किसी दिन 'init() 'को' shared_ptr 'वापस करने के लिए दोबारा प्रतिक्रिया दी जाती है और इस मान को कॉपी करने और स्मृति में' टी' रखने के बजाय, आपको संकलन त्रुटि मिलती है और यह तय करने का मौका होता है कि 'shared_ptr ', 'weak_ptr' का उपयोग करना है या नहीं ', या' टी & '। – jingyu9575

+1

यही कारण है कि 'ऑटो' जादुई और संभावित रूप से भ्रमित दोनों है। टेम्पलेट तर्क कटौती नियम का उल्लेख करने के लिए –

उत्तर

19

auto चर की घोषणाओं में प्रयोग किया जाता विनिर्देशक, के रूप में template argument deduction में इस्तेमाल एक ही नियमों के साथ अपने प्रकार deduces।

अपने पहले उदाहरण पर विचार करें (यानी, auto p1 = &i;)। auto विनिर्देशक के प्रकार इस प्रकार निष्कर्ष निकाला है:

  1. auto एक काल्पनिक प्रकार टेम्पलेट पैरामीटर साथ बदल दिया है (उदाहरण के लिए, U p1 = &i;)।
  2. &i प्रकार int* है, इस प्रकार कोई आश्चर्य नहीं है और टेम्पलेट कटौती नियमों के अनुसार Uint* पर ले जाया गया है।

अब अपने दूसरे उदाहरण (यानी, auto *p2 = &i) पर विचार करें।

  1. फिर auto एक काल्पनिक प्रकार टेम्पलेट पैरामीटर साथ बदल दिया है (उदाहरण के लिए, U* p1 = &i;)।
  2. &i प्रकार int* है, इस प्रकार टेम्पलेट कटौती नियम U के अनुसार int पर घटाया जाता है।

जैसे, auto *p2 = &i; में प्लेसहोल्डर प्रकार auto सही ढंग से int और नहीं int* के रूप में के रूप में निष्कर्ष निकाला जाएगा, उस प्रकार int** की p2 से किया जा रहा में परिणाम होगा, जैसा कि आप की उम्मीद हो सकता है।

+2

+1। हालांकि, एक नोट के रूप में, 'ऑटो' प्रकार की कटौती में टेम्पलेट प्रकार की कटौती से एक छोटा अंतर होता है (मेयर्स के प्रभावी आधुनिक सी ++ देखें), हालांकि मुझे विवरण याद नहीं है। –

+3

अंतर घुंघराले ब्रेस प्रारंभकर्ता सूचियों के कारण है: ऑटो x = {1,2,3}। स्कॉट मेयर्स पुस्तक (प्रभावी आधुनिक सी ++) से उद्धृत: "ऑटो टाइप कटौती आमतौर पर टेम्पलेट प्रकार की कटौती के समान होती है, लेकिन ऑटो टाइप कटौती मानती है कि एक ब्रेसिड प्रारंभकर्ता एक std :: startizer_list का प्रतिनिधित्व करता है, और टेम्पलेट प्रकार की कटौती नहीं करता है।" – spraetor

84

अंतर है, जबकि दूसरे मामले में स्वत: int को निष्कर्ष निकाला है कि पहले मामले में स्वत: int* को निष्कर्ष निकाला है, जिसमें दोनों p1 और p2 प्रकार int* का किया जा रहा है परिणाम है। ऑटो के लिए प्रकार का कटौती तंत्र टेम्पलेट तर्कों के बराबर है। अपने उदाहरण में टाइप कटौती इसलिए

template<typename T> 
void foo(T p1); 

template<typename T> 
void bar(T* p2); 

int main() 
{ 
    int i; 
    foo(&i); 
    bar(&i); 
} 

जहां दोनों कार्यों के रूप में प्रकार शून्य (int *) instantiated कर रहे हैं करने के लिए समान है, लेकिन पहले मामले में T जबकि दूसरे मामले T में int टाइप है int* को निष्कर्ष निकाला जाता है।

+8

बराबर टेम्पलेट त्वरण डालने के लिए ऊपर उठाया गया –