代码之家  ›  专栏  ›  技术社区  ›  Tomilov Anatoliy

按T匹配nullptr*

  •  3
  • Tomilov Anatoliy  · 技术社区  · 9 年前

    使用 boost::variant 指向AST节点的指针,可以包含特殊类型的值 std::nullptr_t ,表示空虚,我面临的问题是:表单的普通访问者 [] (auto /* const */ * p) { /* use p */; } 或形式:

    struct V
    {
        template< typename T >
        void operator () (T /* const */ * p)
        { /* use p */; }
    };
    

    无法处理的价值 标准::nullptr_t 类型

    人们可以想象有很多变通方法,但问题是:有没有很好的解释为什么没有(很可能是高度受限的) decltype(*nullptr) 键入语言( *nullptr 格式错误 std::remove_pointer_t< std::nullptr_t > 标准::nullptr_t 在里面 利比亚银行++ )? 这有理论上的原因吗?

    1 回复  |  直到 9 年前
        1
  •  4
  •   Mr Lister hawi    9 年前

    有没有很好的解释,为什么语言中没有(很可能是高度受限的)decltype(*nullptr)类型(*null ptr格式不正确,而libc++中的std::remove_pointer_t<std::nullptr_t>是std:;nullptr-t)?这有理论上的原因吗?

    我认为要回答这个问题,我们必须看看 N1601 由Herb Sutter和Bjarne Stroustrup提出。

    有几个部分对我来说特别突出

    4.10[转换.ptr]

    空指针常量或nullptr_t类型的对象可以转换为 指针类型;结果是该类型的空指针值

    和4.11[conv.mem]:

    空指针常量(4.10)或类型为nullptr_t(4.10 成员类型;结果是该类型的空成员指针值

    因此,如果通过 nullptr nullptr_t 是给定指针类型的空指针,那么取消对它的引用(例如,通过 decltype(*nullptr) 将与取消引用任何其他类型的空指针相同。(在特定情况下 delctype(*nullptr) 我认为这类似于取消引用空值 void* ). 也就是说,你不应该这么做。

    标准::remove_pointer_t<标准::nullptr_t>是标准::nullptr_t

    这是真的,原因很简单,但“为什么”更难理解。

    原因:

    std::nullptr_t 是空指针文本nullptr的类型。它是一个独特的类型,本身不是指针类型或指向成员类型的指针。

    鉴于此 std::remove_pointer_t 不会有任何影响,因为 空ptr_t 不是指针类型。

    为什么

    在N1601,Sutter和Stroustrup表示

    nullptr_t不是保留字。它是在<cstddef>。我们预计不会在实际程序中看到nullptr_t的直接使用。

    事实上,这就是实际发生的事情。例如,Clang 3.9.0在stddef.h中有以下内容:

    namespace std { typedef decltype(nullptr) nullptr_t; }
    using ::std::nullptr_t;
    

    (而且他们说得对 空ptr_t 出现在许多节目中)。

    这仍然无法解释 为什么? 它是这样定义的。要做到这一点,我认为我们需要回到更远的时间 N1488 也是由萨特和斯特劳斯特鲁普写的,他们说:

    该值的使用 0 表示不同的东西(指针常量和 int )在C++中导致 至少自1985年以来,在教学、学习和使用C++方面存在的问题。特别地:

    • 区分零和零。空指针和整数 0 无法区分 很好地解决了过载问题。例如,给定两个重载函数 f(int) f(char*) , 呼叫 f(0) 明确地决心 f(整数) 。无法向 f(字符*) 用一个 空指针值而不写入显式转换(即。, f((char*)0) )或使用命名变量。 注意,这意味着今天的空指针, 0 ,没有可发音类型。

    • 命名为空。此外,程序员经常要求空指针常量具有 名称(而不仅仅是 0 ). 这是宏 NULL 存在,尽管该宏 不充分的(如果空指针常量具有类型安全名称,这也将解决 上一个问题,因为它可以与整数区分开来 0 用于过载解决和 一些错误检测。)

    我认为这很好地解释了为什么;程序员需要一种方法来区分重载中的指针和整数值,因为 无效的 通常定义为 0 ,通常被解释为整数类型,没有简单的方法强制重载解析来选择指针重载。现在我们有了 空指针 ,我们可以区分指针和非指针类型,这完全避免了这个问题。