当前位置: 首页 > article >正文

学习std::is_base_of笔记

1、std::is_base_of简介

在现代 C++ 中,模板元编程(Template Metaprogramming)是一种非常强大的编程技巧,它让我们能够在编译期进行类型推导和约束。而 std::is_base_of 是一个重要的工具,可以用来检查一个类型是否是另一个类型的基类。std::is_base_of 是 C++11 引入的一个类型特性(Type Trait),位于头文件 <type_traits> 中。它用于检查一个类型 Base 是否是另一个类型 Derived 的基类。如果 Base 是 Derived 的基类,或者两者是同一类型,std::is_base_of<Base, Derived>::value 将返回 true,否则返回 false。它的定义原型如下:

namespace std {
    template <class Base, class Derived>
    struct is_base_of;
}

2、std::is_base_of 的特点

  • 同一类型返回 true,std::is_base_of<Base, Base> 会返回 true,因为类型被视为自身的基类。
  • 支持多级继承,即使继承链是多级的,std::is_base_of 依然能够正确判断。例如:
struct A {};
struct B : A {};
struct C : B {};

std::is_base_of<A, C>::value; // true
  • 对非派生关系返回 false,如果两个类型之间没有继承关系,std::is_base_of 会返回 false
  • 不需要对象,std::is_base_of 只检查类型之间的关系,而不依赖于实际的对象。
  • 检测 private 继承也返回 true,无论继承是 public、protected 还是 private,只要存在继承关系,std::is_base_of 都会返回 true。
struct A {};
struct B : private A {};

std::is_base_of<A, B>::value; // true

3、应用场景

  • 简单例子
#include <iostream>
#include <type_traits>

struct Base {};
struct Derived : Base {};
struct Unrelated {};

int main() {
    std::cout << std::boolalpha;

    // Base 是 Derived 的基类
    std::cout << "Base is base of Derived: " << std::is_base_of<Base, Derived>::value << '\n';

    // Derived 不是 Base 的基类
    std::cout << "Derived is base of Base: " << std::is_base_of<Derived, Base>::value << '\n';

    // Base 不是 Unrelated 的基类
    std::cout << "Base is base of Unrelated: " << std::is_base_of<Base, Unrelated>::value << '\n';

    // 一个类型是其自身的基类
    std::cout << "Base is base of Base: " << std::is_base_of<Base, Base>::value << '\n';

    return 0;
}

输出结果如下:

Base is base of Derived: true
Derived is base of Base: false
Base is base of Unrelated: false
Base is base of Base: true
  • 模板启动/禁用
    结合 std::enable_if 使用,限制模板函数或类的实例化,示例:
#include <iostream>
#include <type_traits>

struct Base {};
struct Derived : Base {};
struct Unrelated {};

// 仅当 T 是 Base 的派生类时,启用此模板
template <typename T>
typename std::enable_if<std::is_base_of<Base, T>::value>::type
process(const T&) {
    std::cout << "T is derived from Base\n";
}

int main() {
    Derived d;
    process(d); // 编译通过

    Unrelated u;
    // process(u); // 编译错误

    return 0;
}
  • 工厂模式
    在设计工厂模式时,可以通过 std::is_base_of 确保所有创建的对象都继承自特定的基类。
#include <iostream>
#include <type_traits>

struct Base {
    virtual void speak() { std::cout << "I am Base\n"; }
};

struct Derived : Base {
    void speak() override { std::cout << "I am Derived\n"; }
};

struct Unrelated {};

template <typename T>
Base* create() {
    static_assert(std::is_base_of<Base, T>::value, "T must derive from Base");
    return new T();
}

int main() {
    Base* b = create<Derived>(); // 编译通过
    b->speak();

    // Base* u = create<Unrelated>(); // 编译错误

    delete b;
    return 0;
}

4、注意事项

  • 不能检测非继承关系的相容性,如果两个类型可以通过隐式转换兼容,但不存在继承关系,std::is_base_of 仍会返回 false。

http://www.kler.cn/a/520668.html

相关文章:

  • 字节iOS面试经验分享:HTTP与网络编程
  • leetcode 面试经典 150 题:有效的括号
  • Linux系统之gzip命令的基本使用
  • WinForm保持一个窗口在另一个全屏窗口的上面
  • 案例研究丨浪潮云洲通过DataEase推进多维度数据可视化建设
  • 積分方程與簡單的泛函分析8.具連續對稱核的非齊次第II類弗雷德霍姆積分算子方程
  • 可以称之为“yyds”的物联网开源框架有哪几个?
  • [java] 集合-ArrayList篇
  • Rust:Rhai脚本编程示例
  • 设计模式Python版 原型模式
  • 【Validator】字段验证器介绍,及基本使用go案例
  • MongoDB中的横向扩容数据分片
  • STM32完全学习——RT-thread在STM32F407上移植
  • Spring无法解决的循环依赖
  • 通义灵码插件保姆级教学-IDEA(安装及使用)
  • 重构开源LLM分类:从二分到三分的转变
  • 【数据结构】_链表经典算法OJ(力扣版)
  • Mysql主从复制+MHA实验笔记[特殊字符]
  • git的理解与使用
  • HarmonyOS简介:高效开发与测试
  • 三维网格处理开源软件meshlab源码编译
  • 1.23 补题 寒假训练营
  • 图的矩阵表示
  • GEE | Sentinel-2影像监督分类、精度评估并导出
  • XSLT 编辑 XML:深度解析与实际应用
  • React应用深度优化与调试实战指南