gpt4 book ai didi

c++ - C++ nullptr实现如何工作?

转载 作者:行者123 更新时间:2023-12-01 09:01:51 25 4
gpt4 key购买 nike

我很好奇知道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){};
    };

    最佳答案

    I am curious to know how nullptr works.



    它以最简单的方式工作:通过命令。之所以有效,是因为C++标准说它有效,并且它之所以起作用,是因为C++标准说实现必须使其以这种方式工作。

    重要的是要认识到不可能使用C++语言的规则来实现 std::nullptr_t。从 std::nullptr_t类型的空指针常量到指针的转换不是用户定义的转换。这意味着您可以从一个空指针常量转到一个指针,然后通过用户定义的转换到某种其他类型,全部都在一个隐式转换序列中进行。

    如果将 nullptr_t实现为一个类,则不可能。转换运算符表示用户定义的转换,并且C++的隐式转换序列规则不允许在这种序列中进行多个用户定义的转换。

    因此,您发布的代码非常类似于 std::nullptr_t,但仅此而已。它不是该类型的合法实现。这可能来自较旧的编译器版本(出于向后兼容的原因而保留),之后编译器为 std::nullptr_t提供了适当的支持。您可以通过 #define s nullptr看到这一点,而C++ 11则说 nullptr是关键字,而不是宏。

    C++无法实现 std::nullptr_t,就像C++无法实现 intvoid*一样。只有实现可以实现那些东西。这就是使其成为“基本类型”的原因;这是语言的一部分。

    its value can be converted to integral type identically to (void*)0, but not backwards;



    从空指针常量到整数类型都有 no implicit conversion。从 0转换为整数类型,但这是因为它是整数文字零,即...整数。
    nullptr_t可以转换为整数类型(通过 reinterpret_cast),但是只能隐式转换为指针和 bool

    关于c++ - C++ nullptr实现如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61283569/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com