将空点与 T * 匹配
matching nullptr by T *
使用指向 AST 节点的指针boost::variant
,这些节点可以包含特殊类型std::nullptr_t
的值,表示空,我遇到了问题:表单[] (auto /* const */ * p) { /* use p */; }
或表单的通用访问者:
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 >
在libc ++中std::nullptr_t
(?这有理论上的原因吗?
有没有很好的解释为什么语言中没有(很可能是高度受限的(decltype(*nullptr(类型(*nullptr 格式不正确,libc ++ 中的 std::remove_pointer_t<std::nullptr_t> 是 std::nullptr_t(?这有理论上的原因吗?
我认为要回答这个问题,我们必须看看Herb Sutter和Bjarne Stroustrup提出的N1601。
有几个部分对我来说很突出,特别是
4.10 [转换]
空指针常量或类型 nullptr_t 的对象可以转换为 指针类型;结果是该类型的空指针值
和 4.11 [conv.mem]:
可以将空指针常量 (4.10( 或类型 nullptr_t (4.10( 的对象转换为指针 成员类型;结果是该类型的 NULL 成员指针值
因此,如果传递 nullptr
或 nullptr_t
的结果是给定指针类型的空指针,那么取消引用它(例如,通过 decltype(*nullptr)
与取消引用任何其他类型的空指针相同是有意义的。(在delctype(*nullptr)
的特定情况下,我相信这类似于取消引用空void*
(。也就是说,你不应该这样做。
std::remove_pointer_t<std::nullptr_t> is std::nullptr_t
这是真的原因很容易,但为什么更难理解。
原因:
std::nullptr_t 是空指针文本 nullptr 的类型。它是一种独特的类型,它本身不是指针类型或指向成员类型的指针。
鉴于此,std::remove_pointer_t
不会产生任何影响是有道理的nullptr_t
因为它不是指针类型。
为什么
在N1601中,萨特和斯特劳斯特鲁普说
nullptr_t不是一个保留的词。它是在
中定义的 decltype(nullptr( 的 typedef(如其_t typedef 所示(。我们预计不会在实际程序中直接使用nullptr_t。
事实上,这似乎就是实际发生的事情。例如,Clang 3.9.0在stddef.h中具有以下内容:
namespace std { typedef decltype(nullptr) nullptr_t; }
using ::std::nullptr_t;
(而且他们关于在许多节目中出现的nullptr_t
不多是正确的(。
这仍然不能解释为什么它被这样定义。要做到这一点,我认为我们需要回到更远一点的N1488,也是萨特和斯特劳斯特鲁普说的:
这种值的使用
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
,我们可以区分指针和非指针类型,这完全避免了这个问题。
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 基于ELO的团队匹配算法
- 没有用于初始化C++中的变量模板的匹配构造函数
- 调用'begin(int [n])'没有匹配函数
- 将模板与类模板扣除占位符参数匹配
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- Qt SQLite没有查询或参数计数不匹配
- 模板参数推导失败,函数参数/参数不匹配
- 错误 没有与参数列表匹配的重载函数"getline"实例
- 在使用累加时,C++中的运算符+不匹配
- 错误:调用'getline'没有匹配函数
- C++ 与操作员不匹配<<
- 我怎样才能将所有子目录与 cmake 自动匹配
- C++:编译时检查匹配的函数调用对?
- 匹配函数指针作为模板参数?
- 矩形类中没有匹配函数
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- std::vector 没有重载函数的实例与参数列表匹配