2012-03-31 10 views
16

मैं C++ 11 मानक से नहीं बता सकता अगर nullptr_t में एक डिफ़ॉल्ट कन्स्ट्रक्टर है। दूसरे शब्दों में, वैध निम्नलिखित ?:एक डिफ़ॉल्ट रचनात्मक प्रकार nullptr_t है?

nullptr_t n; 

जीसीसी और VC++ ऊपर कोड की अनुमति देते हैं, लेकिन बजना नहीं करता है। मुझे मानक में कुछ भी नहीं मिला है जिसमें यह निर्दिष्ट किया गया है कि इसमें डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है, और जो मुझे मिल सकता है, वह बताता है कि इसे करना चाहिए। यह मेरे लिए मायने रखता है क्योंकि मैं पुराने कंपाइलर समर्थन के लिए नलप्टर के मूल फ़ॉलबैक कार्यान्वयन को लिख रहा हूं और मुझे यह जानने की आवश्यकता है कि मुझे इसे एक डिफ़ॉल्ट कन्स्ट्रक्टर देने की आवश्यकता है या नहीं।

+0

मैंने सोचा था कि आपको एक सादे सूचक प्रकार के रूप में 'nullptr_t' को संभालना था, यानी एक वर्ग के रूप में नहीं। तो मैं मान रहा हूं कि 'nullptr_t n;' _uninitialised_ चर बनाता है; आपको माना जाता है कि 'nullptr_t n = nullptr;' स्पष्ट रूप से लिखें। लेकिन मेरे पास सी ++ 11 कंपाइलर नहीं है, इसलिए मैं जांच नहीं कर सकता। और मुझे लगता है कि मैं इसे औपचारिक चश्मे में कहाँ पढ़ता हूं ... –

+0

FWIW, क्लैंग "nullptr_t n;" स्वीकार करता है यहाँ। –

उत्तर

17

स्टैंडर्ड क्या कहते हैं

मानक कहते हैं (18,2)

nullptr_t इस प्रकार परिभाषित किया गया है:

namespace std { 
    typedef decltype(nullptr) nullptr_t; 
} 

प्रकार जिसके लिए nullptr_t पर्याय है विशेषताओं में वर्णित है 3.9.1 और 4.10।

कहाँ 3.9.1 मूल रूप से कहना है कि वह void* और 4.10 के रूप में एक ही आकार का होना चाहिए nullptr के लिए रूपांतरण नियम निर्दिष्ट करता है।

संपादित करें: 3.9.9 इसके अलावा स्पष्ट रूप से कहा गया है कि nullptr_t एक अदिश प्रकार है, जो के लिए उम्मीद प्रारंभ नियमों का मतलब है में निर्मित प्रकार 8.5 लागू होते हैं:

  • डिफ़ॉल्ट-प्रारंभ (nullptr_t n;) है, जो n के मूल्य को अपरिभाषित करता है। जैसा कि जोहान्स शाएब ने सही तरीके से बताया, यह क्लैंग के नवीनतम संस्करण के साथ ठीक है।
  • मूल्य प्रारंभ (nullptr_t n = nullptr_t();) है, जो करने के लिए 0.

यह व्यवहार n initializes उदा के समान है int, इसलिए nullptr_t निश्चित रूप से डिफ़ॉल्ट-रचनात्मक है। यहां दिलचस्प सवाल यह है कि nullptr_t के लिए अनिर्धारित मूल्य होने का क्या अर्थ है? दिन के अंत में, nullptr_t के लिए केवल एक अर्थपूर्ण संभव मूल्य है, जो nullptr है। इसके अलावा प्रकार केवल nullptr शाब्दिक के अर्थशास्त्र के माध्यम से परिभाषित किया जाता है। क्या ये अर्थशास्त्र अभी भी एक प्रारंभिक मूल्य के लिए आवेदन करते हैं?

क्यों उस सवाल का अभ्यास

आप प्रकार nullptr_t का एक नया चर घोषित करने के लिए नहीं करना चाहती में कोई फर्क नहीं पड़ता। उस प्रकार का एकमात्र सार्थक अर्थात् पहले से ही nullptr शाब्दिक के माध्यम से व्यक्त किया गया है, इसलिए जब भी आप nullptr_t प्रकार के अपने कस्टम चर का उपयोग करेंगे, तो आप nullptr का भी उपयोग कर सकते हैं।

क्या अभ्यास

इसका एकमात्र अपवाद तथ्य यह है कि आप प्रकार nullptr_t के गैर प्रकार टेम्प्लेट पैरामीटर ले जा सकते हैं से आता है में फर्क पड़ता है। इस मामले के लिए, यह जानना उपयोगी है कि कौन से मान nullptr_t में परिवर्तित हो सकते हैं, जो 4 में वर्णित है।10:

एक नल पॉइंटर लगातार एक अभिन्न निरंतर अभिव्यक्ति (5.19) पूर्णांक प्रकार है कि शून्य या प्रकार std::nullptr_t के prvalue का मूल्यांकन की prvalue है। [...] अभिन्न प्रकार के एक शून्य सूचक स्थिर को std::nullptr_t के प्रकार के रूप में परिवर्तित किया जा सकता है।

कौन सा मूल रूप से करता है सिर्फ तुम क्या उम्मीद थी: आप

nullptr_t n = 0; // correct: 0 is special 

नहीं बल्कि

nullptr_t n = 42; // WRONG can't convert int to nullptr_t 

दोनों जीसीसी 4.6 लिख सकते हैं और बजना SVN यह अधिकार मिलता है।

+1

आप कक्षाओं के गैर-वर्गों के लिए सच है जो कुछ सामान्यीकृत करने की गलती कर रहे हैं। गैर-वर्गों में कोई सदस्य कार्य नहीं है। –

+1

गैर-वर्ग प्रकार सदस्य कार्य किए बिना डिफ़ॉल्ट-रचनात्मक हो सकते हैं। यह एक सदस्य कार्य करने के अर्थ में एक डिफ़ॉल्ट कन्स्ट्रक्टर होने के बारे में नहीं है, लेकिन एक डिफ़ॉल्ट-रचनात्मक प्रकार की अवधारणा को पूरा करने के अर्थ में। – ComicSansMS

+0

मानक से: "जिस प्रकार के लिए nullptr_t समानार्थी है, 3.9.1 और 4.10 में वर्णित विशेषताओं में है।" अनुभाग 3.9.1 (मौलिक प्रकार) पर जाएं और जानें कि आप int-typed, float-typed, वास्तव में, nullptr_t-टाइप किए गए चर घोषित कर सकते हैं। –

1

जबकि nullptr ही भाषा को नया है, std::nullptr_t सिर्फ एक अनाम प्रकार का एक अन्य नाम है, उर्फ ​​cstddef इस तरह की घोषणा: एक ओर जहां

typedef decltype(nullptr) nullptr_t; 

nullptr_t, एक typedef और नहीं एक भाषा जा रहा है कीवर्ड, को मौलिक प्रकार के रूप में सूचीबद्ध नहीं किया गया है, इसे मूलभूत प्रकार के रूप में व्यवहार करने के लिए निर्दिष्ट किया गया है (और नहीं, उदाहरण के लिए, एक पॉइंटर प्रकार या क्लास प्रकार के रूप में)। इसलिए इसमें एक डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है, लेकिन आप अभी भी एक वैरिएबल घोषित कर सकते हैं जैसा आपने किया है। आपका चर प्रारंभ नहीं हुआ है और मुझे आश्चर्य है कि इसका उपयोग क्या हो सकता है और आपको clang से वास्तव में क्या त्रुटि संदेश मिला है।

here भी देखें।

+0

मुझे लगता है कि "मौलिक प्रकार" खंड में nullptr_t के मानों के बारे में बात करने का अनुमान है कि nullptr_t एक मौलिक प्रकार है। मौलिक प्रकारों के किस प्रकार के बारे में कोई स्पष्ट सूची नहीं है, जिसका अर्थ है कि किसी को "मौलिक प्रकारों" में उल्लिखित सभी प्रकारों पर पुनरावृत्ति करके उन्हें इकट्ठा करना होगा। और यह बहुत समझ में आता है कि यह वैसे भी एक मौलिक प्रकार है। –

+4

ध्यान दें कि आप यह नहीं कह सकते "टाइप nullptr_t लाइब्रेरी टाइपपीफ है"। एक टाइपिफ़ * नहीं * एक नया प्रकार पेश करता है। यह बस मौजूदा प्रकार के लिए उपनाम बनाता है। जिस प्रकार "nullptr_t" उपनाम * भाषा द्वारा प्रस्तुत किया गया है। –

+0

@ जोहान्सचैब-लिटब - ठीक है, इस बिंदु को और स्पष्ट करने के लिए प्रश्न संपादित करें। यह बिंदु है, 'nullptr' के प्रकार का कोई नाम या उपनाम नहीं है जब तक कि उपनाम असाइन नहीं किया जाता है (मानक लाइब्रेरी हेडर फ़ाइल का उपयोग करके सबसे अच्छा किया जाता है)। –

संबंधित मुद्दे