为什么nullptr是核心语言的一部分,而nullptr_t是STL的一部分?

8
据我所知,nullptr是核心语言的一部分。
引用C++11标准:(18.2/9)

nullptr_t定义如下:

namespace std { typedef decltype(nullptr) nullptr_t; }

并且在头文件<cstddef>中定义。

3
好的,我将尽力为您进行翻译。相关/可能重复:https://dev59.com/GVkT5IYBdhLWcg3wFryj问题:为什么我可以在没有包含STL的情况下使用nullptr?答案:nullptr是C++11中的关键字,不需要包含任何头文件就可以使用。然而,在旧版本的C++中,没有定义nullptr,因此您需要包含<cstdlib>头文件来使用NULL宏。 - NathanOliver
5
如果你愿意接受decltype(nullptr),就不需要使用nullptr_t了。nullptr_t并不是核心概念,它只是一个辅助工具。 - François Andrieux
有时候你需要使用 nullptr_t: "如果两个或多个重载函数接受不同的指针类型,则需要一个接受空指针参数的 std::nullptr_t 重载函数。"(参见 std::nullptr_t 的 cppreference)。 - Adrian Mole
2
@Adrian 我猜你是想回复我的评论。如果是这样,那么我说如果你愿意使用decltype(nullptr),就不需要nullptr_t。你可以使用decltype(nullptr)代替nullptr_tnullptr_t只是decltype(nullptr);的方便别名。你应该使用nullptr_t,我的评论旨在说明为什么nullptr_t可能不是核心语言的一部分。 - François Andrieux
同时,通过将nullptr作为语言的一部分,可以更轻松地确保它按照应有的方式工作,因为您可以轻松地制定具体规则。 - Phil1970
3个回答

7

因为它可以。在C++标准化过程中,核心语言的改动应该尽可能少,同时添加新功能。

nullptr 取代了使用 0 表示空指针和零的含义。使用 0 会因为明显的原因而产生问题,比如 f(0) 调用的是 f(int) 还是 f(int*)?所以一个全新的字面值被加入到了核心语言: nullptr。它的类型就是 decltype(nullptr) ,所以也加入了一个简写: nullptr_t

namespace std {
    using nullptr_t = decltype(nullptr);
}

谢谢,但nullptr本身可以成为STL的一部分... nullptr是否包含在核心语言中,以免需要开发人员包含任何头文件? - embedc
@embedc 任何像 std::size_t 这样的 std 类型定义都是通过头文件提供的,那又怎样呢? - πάντα ῥεῖ
2
@embedc nullptr是一个字面量,就像5'a'"hello"一样。虽然我无法想象它是什么,但我敢打赌有一个很好的技术原因,为什么空指针字面量比在std中具有类似于nullptr的对象更好。编辑:首先,作为字面量,它是一个prvalue,所以你不能取它的地址。对我来说,能够获取nullptr的地址似乎很奇怪。这就像得到true的地址一样。 - François Andrieux
1
这是一个内置的关键字/指针文字。 - Ron

6

引入 nullptr 的提案 N2431 在 1.1 节中指出,不强制用户包含头文件以使用 nullptr 是可取的。

它还指出:“我们不希望在实际程序中看到过多直接使用 nullptr_t ”。因此,将 nullptr_t 添加到库中被认为是更好的选择,而不是创建一个仅用于这个模糊目的的新关键字。此外,如果你不想包含头文件,你可以自己写 decltype(nullptr)


这实际上回答了问题。 - bolov

1

来自cppreference.com:

std::nullptr_t是空指针字面量nullptr的类型。它是一个独立的类型,既不是指针类型也不是成员指针类型。

如果两个或多个重载函数接受不同的指针类型,则需要一个用于std::nullptr_t的重载函数来接受空指针参数。

然后,您可以使用std::nullptr_t解决重载函数调用的歧义。

例如:

void Foo(int* ptr) {}
void Foo(double* ptr) {}
void Foo(std::nullptr_t ptr) {} // This overload is called if Foo(nullptr) is invoked

在这里阅读有关std::nullptr_t的更多信息:https://en.cppreference.com/w/cpp/types/nullptr_t


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接