c++ - std::is_base_of 和 std::is_convertible 之间的区别
问题描述
这两个模板似乎产生了相同的结果。有什么区别,我们什么时候应该使用哪个?
using namespace std;
class A {
};
class B : public A {
};
class C : public A {
};
int main()
{
cout << boolalpha << is_convertible<B, A>::value << '\n';
cout << boolalpha << is_base_of<A, B>::value << '\n';
cout << boolalpha << is_convertible<B, C>::value << '\n';
cout << boolalpha << is_base_of<C, B>::value << '\n';
return 0;
}
运行程序后,我得到了
true
true
false
false
提前致谢!
解决方案
查看 和 的std::is_base_of
文档std::is_convertible
。
以下是一些差异:
#include <type_traits>
struct anything_can_convert_to {
// This constructor constructs from anything
template<class T> anything_can_convert_to(T&&) {}
};
struct can_convert_to_anything {
// This conversion operator can convert to anything
template<class T> operator T() { return *static_cast<T*>(nullptr); }
};
struct cant_convert_to_base;
struct base {
base(const cant_convert_to_base&) = delete;
};
struct public_derived : base {};
struct private_derived : private base {};
struct cant_convert_to_base : base {};
int main() {
#define IS_CONVERTIBLE(FROM, TO) static_assert(std::is_convertible_v<FROM, TO>)
#define IS_NOT_CONVERTIBLE(FROM, TO) static_assert(!std::is_convertible_v<FROM, TO>)
#define IS_BASE_OF(BASE, DERIVED) static_assert(std::is_base_of_v<BASE, DERIVED>)
#define IS_NOT_BASE_OF(BASE, DERIVED) static_assert(!std::is_base_of_v<BASE, DERIVED>)
IS_CONVERTIBLE(int, long);
IS_CONVERTIBLE(int, anything_can_convert_to);
IS_CONVERTIBLE(can_convert_to_anything, int);
IS_NOT_CONVERTIBLE(anything_can_convert_to, int);
IS_CONVERTIBLE(public_derived, base);
IS_NOT_CONVERTIBLE(private_derived, base);
IS_NOT_CONVERTIBLE(cant_convert_to_base, base);
IS_NOT_BASE_OF(int, long);
IS_NOT_BASE_OF(int, anything_can_convert_to);
IS_BASE_OF(base, public_derived);
IS_BASE_OF(base, private_derived);
IS_BASE_OF(base, cant_convert_to_base);
}
你会意识到它们是为了两个不同的东西。就像它听起来的那样:就继承而言,std::is_base_of<Base, Derived>
它是否Base
是 的基类。基本上检查是否:Derived
std::is_convertible<From, To>
To test = (expression of type From);
形成良好。对于继承,如果From
是 的基类,大多数情况下是这种情况To
,但还有很多其他情况是这种情况(例如,使用私有继承,您无法转换为基类,但std::is_base_of
仍然有效。)
推荐阅读
- ios - 使用 JSONDecoder Swift 解码
- javascript - 更改导航栏上的“当前”类
- ios - 带有titleLabel的Swift菱形UIButton
- reactjs - 正确实现 JWT
- python - 绑定到 tkinter 中的列表框似乎不起作用
- typescript - Firebase 管理员 ~ EACCES:权限被拒绝,cloud-functions-emulator.log
- javascript - 如何防止触摸除使用 JavaScript 的元素之外的所有元素?
- reactjs - React Native ScreenProps 未定义函数
- javascript - 导航栏重叠且同时不够长
- node.js - 使用 Apache 和反向代理将 domain.com/api 路由到特定端口