C++ 为什么std::是<;T、 T>;当T是类类型时为true,但当T是内置类型时为false?

C++ 为什么std::是<;T、 T>;当T是类类型时为true,但当T是内置类型时为false?,c++,c++11,c++14,typetraits,C++,C++11,C++14,Typetraits,根据[meta.rel](C++14中的20.10.6),对于类类型T,std::is_base_of为真,但对于内置类型T,std::is_base_of为假。通俗地说,类类型是它们自身的基础,但内置类型不是。这种治疗差异的动机/效用是什么?内置类型不是类,非类的东西不能成为任何东西的基础 如果说有什么让我有点惊讶的话,std::is_base_of即使对于类类型也是正确的,但这可能是类的“可以视为”关系 嗯,我不知道。理论基础可以追溯到很多方面,而且没有很好的记录 is_base_of最初被

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

内置类型不是类,非类的东西不能成为任何东西的基础

如果说有什么让我有点惊讶的话,
std::is_base_of
即使对于类类型也是正确的,但这可能是类的“可以视为”关系


嗯,我不知道。

理论基础可以追溯到很多方面,而且没有很好的记录

is_base_of
最初被称为
is_base_和_派生的
,并在TR1中引入。Dave Abrahams在第3.13节中介绍了一个针对该类的问题:

当前,
是基本的,当
X
Y
都是一样的。这在技术上是正确的(
X
不是它自己的基础 类),但它没有用处。这个定义应该放宽到 当
X
Y
相同时返回true,即使类型不同 实际上是一门课

不幸的是,这一问题没有阐明为什么这一定义没有用处。然而,这一观点在当时(2003年)并不独特。两年前出版的这本书也有同样的特点,在第2.7节中对它的宏
超级子类
也有同样的评论,不过如果你真的不想让一个类被视为自己的基础,这本书还添加了一个变通宏

继续使用第3.12节中的
SUPERSUBCLASS
按继承顺序排列类型列表。在本练习的细节中,利用了
SUPERSUBCLASS(T,T)
为真的事实(为了实现的方便)

到2004年,当
T
是非联合类类型时,
std::is_base_of::value==true
非常有用

进一步阐明了
is\u base\u of
如何适用于非类类型,这一变化导致了您今天看到的措辞。然而,这篇被接受的论文所提出的内容与以下草案()所产生的内容之间存在着广泛的编辑差异。我的意见是编辑大大改进了措辞

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

这是否是最好的设计值得商榷。然而,有足够的特性(例如,
是类
是相同的
)从这些基本特性中构建您所需要的任何东西

这更多的是一段历史,而不是一个直截了当的“为什么”。然而,这个答案的要点是指出,
是经过许多迭代,经过大量时间演变而成的
的基础。每一次迭代在当时都被认为是对过去的进化改进


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

如果您需要
T
成为给定类型,或从中派生出来,
std::is_base_of
正确地表达了它。如果它不是自反的,那么您几乎总是必须将它与
std::is_same
一起使用。此外,大多数具有子类型的系统都使用自反性。@DanielKO:现在的情况是,我怀疑在某些情况下,在应用
std::is_basic\u of
之前,您必须使用
std::is_base\u of
来处理基本类型和类类型被
std::is_basic\u of
区别对待的事实。不清楚的是,这种不对称给你带来了什么。@DanielKO:但对于某些类型,它却没有。你不能编写
class Foo:int{}用于任何
Foo
。因此,即使
int
是-a
int
,您仍然不能有一个包含和
int
的层次结构。嗯(顺便说一句,这可能是一种编写不透明typedef的好方法)。