मैं यह जानने के लिए उत्सुक हूं कि कैसे nullptr
काम करता है। मानक N4659 और N4849 कहते हैं:
- इसे टाइप करना होगा
std::nullptr_t
; - आप इसका पता नहीं लगा सकते हैं;
- इसे सीधे एक पॉइंटर और पॉइंटर को सदस्य में बदला जा सकता है;
sizeof(std::nullptr_t) == sizeof(void*)
;- इसका रूपांतरण
bool
हैfalse
; - इसके मूल्य को अभिन्न प्रकार से अभिन्न रूप में परिवर्तित किया जा सकता है
(void*)0
, लेकिन पीछे की ओर नहीं;
तो यह मूल रूप से एक ही अर्थ के साथ एक स्थिर है (void*)0
, लेकिन इसका एक अलग प्रकार है। मैंने std::nullptr_t
अपने डिवाइस पर कार्यान्वयन पाया है और यह इस प्रकार है।
#ifdef _LIBCPP_HAS_NO_NULLPTR
_LIBCPP_BEGIN_NAMESPACE_STD
struct _LIBCPP_TEMPLATE_VIS nullptr_t
{
void* __lx;
struct __nat {int __for_bool_;};
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
operator _Tp* () const {return 0;}
template <class _Tp, class _Up>
_LIBCPP_INLINE_VISIBILITY
operator _Tp _Up::* () const {return 0;}
friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
friend _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return false;}
};
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t __get_nullptr_t() {return nullptr_t(0);}
#define nullptr _VSTD::__get_nullptr_t()
_LIBCPP_END_NAMESPACE_STD
#else // _LIBCPP_HAS_NO_NULLPTR
namespace std
{
typedef decltype(nullptr) nullptr_t;
}
#endif // _LIBCPP_HAS_NO_NULLPTR
मैं पहले भाग में अधिक दिलचस्पी ले रहा हूं। यह अंक 1-5 को संतुष्ट करता है, लेकिन मुझे पता नहीं है कि इसका उपवर्ग __nat और इससे जुड़ी हर चीज क्यों है। मैं यह भी जानना चाहूंगा कि यह अभिन्न रूपांतरणों पर विफल क्यों है।
struct nullptr_t2{
void* __lx;
struct __nat {int __for_bool_;};
constexpr nullptr_t2() : __lx(0) {}
constexpr nullptr_t2(int __nat::*) : __lx(0) {}
constexpr operator int __nat::*() const {return 0;}
template <class _Tp>
constexpr
operator _Tp* () const {return 0;}
template <class _Tp, class _Up>
operator _Tp _Up::* () const {return 0;}
friend constexpr bool operator==(nullptr_t2, nullptr_t2) {return true;}
friend constexpr bool operator!=(nullptr_t2, nullptr_t2) {return false;}
};
inline constexpr nullptr_t2 __get_nullptr_t2() {return nullptr_t2(0);}
#define nullptr2 __get_nullptr_t2()
int main(){
long l = reinterpret_cast<long>(nullptr);
long l2 = reinterpret_cast<long>(nullptr2); // error: invalid type conversion
bool b = nullptr; // warning: implicit conversion
// edditor error: a value of type "std::nullptr_t" cannot be used to initialize an entity of type "bool"
bool b2 = nullptr2;
if (nullptr){}; // warning: implicit conversion
if (nullptr2){};
};
#ifdef _LIBCPP_HAS_NO_NULLPTR
। ऐसा लगता है कि जब कंपाइलर प्रदान नहीं करता है तो यह एक सर्वोत्तम प्रयास है nullptr
।
nullptr_t
एक मौलिक प्रकार है। इसे एक वर्ग प्रकार के रूप में लागू करना एक अनुरूप कार्यान्वयन नहीं करता है। देखें क्रिस की टिप्पणी
is_class
और is_null_pointer
दोनों एक ही प्रकार के लिए सच नहीं हो सकते। केवल एक विशिष्ट प्रकार के लिए प्राथमिक प्रकार श्रेणी के कार्य सही हो सकते हैं।
nullptr_t
एक मौलिक प्रकार है। कैसेint
लागू किया जाता है?