c++ - 为什么当 T 是类类型时 std::is_base_of<T, T> 为真,而当 T 是内置类型时为假?

标签 c++ c++11 c++14 typetraits

根据 [meta.rel](C++14 中的 20.10.6),对于类类型 T , std::is_base_of<T,T>是的,但对于内置类型 T , std::is_base_of<T,T>是假的。通俗地说,类类型是它们自己的基础,但内置类型不是。这种治疗差异的动机/效用是什么?

最佳答案

基本原理可以追溯到很久以前,并且没有很好的记录。

is_base_of最初称为 is_base_and_derived ,并在 TR1 中引入。 Dave Abrahams 在 N1541 中引入了针对此类的问题。 ,编号 3.13:

Currently, is_base_and_derived<X,Y> returns false when X and Y are the same. This is technically correct (X isn’t its own base class), but it isn’t useful. The definition should be loosened to return true when X and Y are the same, even when the type isn’t actually a class.

不幸的是,该问题没有说明为什么该定义没有用。然而,这种观点在当时(2003 年)并不是唯一的。 Andrei Alexandrescu's Modern C++ Design两年前发布的具有大致相同的特征,并且在第 2.7 节中关于其宏 SUPERSUBCLASS 的评论大致相同,不过如果你真的不希望一个类被认为是它自己的基类,本书还添加了一个变通方法宏。

Modern C++ Design继续使用SUPERSUBCLASS在第 3.12 节中按继承顺序对 Typelist 进行排序。在这个练习的细节中,SUPERSUBCLASS(T, T)是 true 被利用(为了方便实现)。

到 2004 年,TR1 report, N1647 , 采用了 std::is_base_of<T,T>::value == true 的概念在 T 时很有用是非 union 类类型。

N2255进一步阐明如何 is_base_of应该适用于非类类型,而这种更改导致了您今天看到的措辞。然而,这篇被接受的论文提出的内容与以下草稿 (N2284) 中的内容之间存在广泛的编辑差异。我的看法是编辑大大改进了措辞。

为什么 N2255 的未记录理由在非 union 类类型和其他所有类型之间创建了一个划分是 is_base_of历史上回答了有关类型继承层次结构的问题,只有一个方便的“技巧”,即可以通过“is-a”分析将类视为自己的基础。然而,根据该特性的多位作者的说法,不可能参与继承关系的类型不应该有资格作为基类。

这是否是最好的设计还有待商榷。但是,有足够的特征(例如 is_classis_same )可以根据这些基本特征构建您需要的任何东西。

这更像是一段历史,而不是直截了当的“为什么”。然而,这个答案的重点是指出 is_base_of经过大量的迭代,在很长一段时间内进化。每次迭代都被认为是对以前的进化改进。

这一切都归结为:这是委员会认为最有用的规范。但随着规范和设计经过多年的发展,并经过几位作者的努力,不存在好的整体设计文档或基本原理。

关于c++ - 为什么当 T 是类类型时 std::is_base_of<T, T> 为真,而当 T 是内置类型时为假?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28665645/

相关文章:

c++ - ldexp(1, x) 和 exp2(x) 的区别

c++ - 为什么我不能增加简单 constexpr 函数的参数?

c++ - 从 C++ 中派生类的析构函数调用虚函数

c++ - 这对于等待使用std::future wait()返回的函数的CPU使用率更好,还是在循环中检查标志 sleep 一段时间?

c++ - 没有网表条目上下文时如何删除IP地址

c++ - std::declval<void>() 是一个有效的表达式吗?

c++ - 使用 unique_ptr 和原始指针重载全局函数

c++ - GLib 类型的位大小和对更奇异的(想想 16 位字符)平台的可移植性

C++构造函数继承无匹配函数

c++ - 定义类型的正确方法(typedef vs #define)