两者唯一的区别是 std::is_base_of<Base, Derived>
和 std::is_convertible<Derived*, const volatile Base*>
是前者也是如此,当 Base
是一个 私有 基类 Derived
. 但是,什么时候你真的需要知道,如果 Base
是私有基础还是保护基础?用户为什么要关心一个类的内部实现?
作为一个例子,考虑
template <typename T>
struct Foo : T, Bar {};
在这种情况下,是否是 T
继承自 Bar
或任何其他类),即使继承是受保护的。
对于私有继承,可以考虑一个做一些记账的基类。例如每次创建一个实例时都要创建日志条目。现在,同样,当我从第二个类型继承时,如在 template <typename T> struct Foo : T {};
我想知道,如果 T
已经从记账类中继承了,还是我必须自己添加。
你的假设是错误的。
std::is_convertible
涵盖的用例比 std::is_base_of
.
它也适用于用户定义的转换运算符以及asprimitives.Https /gcc.godbolt.orgzJULbVf。
如果一个类私自继承了一个Base类,那就不是内部实现细节,而是对该类的公共接口有影响。比如说防止向基类转换的事实。
下面这个类。
class C
{
operator int() { return 0; }
};
是可以转换为int的。
constexpr bool is_int = std::is_convertible_v<C, int>; // true
然而int不是C的基类
constexpr bool is_base = std::is_base_of_v<int, C>; // false
所以你的前提是,这些函数存在的唯一理由是:
但是,什么时候你真的需要知道Base是一个私有的还是受保护的基?用户为什么要关心一个类的内部实现?
是不正确的。还有其他的用例。