【发布时间】:2015-04-24 07:06:37
【问题描述】:
根据 [meta.rel](C++14 中的 20.10.6),对于类类型 T,std::is_base_of<T,T> 为 true,但对于内置类型 T,std::is_base_of<T,T> 为 false .通俗地说,类类型是它们自己的基础,但内置类型不是。这种治疗差异的动机/效用是什么?
【问题讨论】:
标签: c++ c++11 c++14 typetraits
根据 [meta.rel](C++14 中的 20.10.6),对于类类型 T,std::is_base_of<T,T> 为 true,但对于内置类型 T,std::is_base_of<T,T> 为 false .通俗地说,类类型是它们自己的基础,但内置类型不是。这种治疗差异的动机/效用是什么?
【问题讨论】:
标签: c++ c++11 c++14 typetraits
基本原理可以追溯到很久以前,并且没有很好的记录。
is_base_of 最初称为is_base_and_derived,并在 TR1 中引入。 Dave Abrahams 在N1541,编号 3.13 中介绍了针对此类的问题:
目前,
is_base_and_derived<X,Y>在X和Y时返回 false 是相同的。这在技术上是正确的(X不是它自己的基础 类),但它没有用。定义应该放宽到 当X和Y相同时返回true,即使类型不同 实际上是一个类。
不幸的是,该问题没有说明为什么该定义没有用。然而,这种观点在当时(2003 年)并不是唯一的。两年前发布的Andrei Alexandrescu's Modern C++ Design 具有大致相同的特征,并且在第 2.7 节中关于其宏 SUPERSUBCLASS 的评论也大致相同,尽管如果您真的不希望将一个类视为自己的类,本书还添加了一个变通方法宏基地。
Modern C++ Design 继续在第 3.12 节中使用SUPERSUBCLASS 来按继承顺序对 Typelist 进行排序。在本练习的细节中,充分利用了SUPERSUBCLASS(T, T) 为真这一事实(为了便于实现)。
到 2004 年,TR1 report, N1647 采用了当 T 是非联合类类型时 std::is_base_of<T,T>::value == true 有用的概念。
N2255 进一步阐明了is_base_of 应该如何适用于非类类型,而这种变化导致了您今天看到的措辞。然而,这篇被接受的论文提出的内容与以下草稿 (N2284) 中产生的内容之间存在广泛的编辑差异。我的看法是编辑大大改进了措辞。
N2255 在非联合类类型和其他所有类型之间创建划分的未记录理由是,is_base_of 在历史上回答了有关类型继承层次结构的问题,只有一个方便的“技巧”,一个类可以通过“is-a”分析考虑了自己的基础。然而,根据这一特性的多位作者的说法,不可能参与继承关系的类型不应该有资格作为基类。
这是否是最好的设计还有待商榷。但是,有足够的特征(例如 is_class 和 is_same)可以根据这些基本特征构建您需要的任何东西。
这更像是一段历史,而不是直截了当的“为什么”。然而,这个答案的重点是指出is_base_of 在很长一段时间内经过多次迭代而演变。每次迭代都被认为是对以前的进化改进。
这一切都归结为:这是委员会认为最有用的规范。但随着规范和设计经过多年的发展,并经过几位作者的努力,不存在好的整体设计文档或基本原理。
【讨论】:
Foo写class Foo : int {};。因此,即使int 是int,您仍然不能有涉及和int 的层次结构。嗯。 (此外,这可能是编写不透明类型定义的好方法)。
内置类型不是类,不是类的东西不能是任何东西的基础。
如果有什么我有点惊讶std::is_base_of<T,T> 即使对于类类型也是正确的,但这可能是类的“可以被视为”关系。
嗯,我不知道。
【讨论】:
T 是给定类型或派生自它,std::is_base_of 会正确表达它。如果它不是自反的,您几乎总是必须将它与std::is_same 一起使用。此外,大多数具有子类型的系统都使用自反性。
std::is_base_of 之前使用 std::is_fundamental 以处理基本类型和类类型的事实std::is_base_of 的处理方式不同。尚不清楚的是,这种不对称会给你带来什么。