首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >T*匹配nullptr

T*匹配nullptr
EN

Stack Overflow用户
提问于 2016-02-02 12:49:24
回答 1查看 415关注 0票数 3

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

代码语言:javascript
复制
struct V
{
    template< typename T >
    void operator () (T /* const */ * p)
    { /* use p */; }
};

无法处理std::nullptr_t类型的值。

人们可以想象到有很多变通办法,但问题日益突出:为什么在语言中没有(非常可能是高度受限的) decltype(*nullptr)类型(*nullptr是错误的,std::remove_pointer_t< std::nullptr_t >std::nullptr_t in libc++),这有很好的解释吗?这是否有理论上的原因?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-02 13:29:32

有很好的解释吗?为什么在语言中没有(非常可能是高度限制的)解密类型(*nullptr是错误的,std::remove_pointer_t< std::nullptr_t > std::nullptr_t在libc++中)?这是否有理论上的原因?

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

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

4.10 conv.ptr

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

和4.11 conv.mem

可以将空指针常量(4.10)或nullptr_t类型的对象(4.10)转换为成员类型的指针;结果是该类型的空成员指针值。

因此,如果传递nullptrnullptr_t的结果是给定指针类型的空指针,那么取消引用它(例如,通过decltype(*nullptr) )将与取消引用任何其他类型的空指针相同。(在delctype(*nullptr)的具体例子中,我认为它类似于取消引用空void*)。也就是说,你不应该这么做。

std::remove_pointer_t< std::nullptr_t > is std::nullptr_t

这是正确的理由是很容易的,但原因是很难理解。

原因是:

T是空指针文本nullptr的类型。它本身不是指针类型,也不是成员类型的指针,这是一个独特的类型。

考虑到这一点,std::remove_pointer_t不会产生任何影响,因为nullptr_t不是指针类型。

为什么

在N1601中,Sutter和Stroustrup说

nullptr_t不是一个保留字。中定义的解密类型(Nullptr)的类型类型(Nullptr)。我们不希望看到在实际程序中直接使用nullptr_t。

事实上,这似乎就是实际发生的情况。例如,clang3.9.0在stddef.h中有如下内容:

代码语言:javascript
复制
namespace std { typedef decltype(nullptr) nullptr_t; }
using ::std::nullptr_t;

(而且他们说得对,在许多程序中出现的nullptr_t并不多)。

这仍然不能解释为什么它被定义为这样。要做到这一点,我认为我们需要回到更远一点的N1488,也就是Sutter和Stroustrup,他们说:

使用0值来表示C++中的不同事物(指针常量和int)至少自1985年以来在教学、学习和使用C++方面造成了问题。特别是:

  • 区分零和零。对于过载解析,空指针和整数0不能很好地区分。例如,给定两个重载函数f(int)f(char*),调用f(0)将明确地解析为f(int)。如果不写入显式强制转换(即f(char*) )或使用命名变量,就无法用空指针值编写对f((char*)0)的调用。请注意,这意味着今天的空指针0没有可说话的类型。
  • 命名为空。此外,程序员经常要求空指针常量有一个名称(而不仅仅是0)。这是宏NULL存在的原因之一,尽管该宏是不够的。(如果空指针常量具有类型安全名称,则还可以解决前面的问题,因为可以将其与整数0区分开来,以进行过载解析和一些错误检测。)

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35153996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档