어떻게 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
모두 동일한 종류의 사실이 될 수 없습니다. 특정 유형에 대해서는 기본 유형 범주 함수 중 하나만 true를 반환 할 수 있습니다.
nullptr_t
기본 유형입니다. 어떻게int
구현됩니까?