学习std::is_base_of笔记

news/2025/1/30 8:07:00/

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.ppmy.cn/news/1567838.html

相关文章

Python 函数魔法书:基础、范例、避坑、测验与项目实战

Python 函数魔法书&#xff1a;基础、范例、避坑、测验与项目实战 内容简介 本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南&#xff0c;旨在帮助读者从基础入门到项目实战&#xff0c;全面提升编程能力。文章结构由 5 个版块组成&#xff0c;内容层层递进…

使用国内镜像加速器解决 Docker Hub 拉取镜像慢或被屏蔽的问题

一、问题背景 Docker Hub 是 Docker 默认的镜像仓库&#xff0c;但由于网络限制&#xff0c;国内用户直接拉取镜像可能面临以下问题&#xff1a; 下载速度极慢&#xff08;尤其是大镜像&#xff09;。连接超时或完全被屏蔽&#xff08;部分网络环境&#xff09;。依赖国外源的…

python:斐索实验(Fizeau experiment)

斐索实验&#xff08;Fizeau experiment&#xff09;是在1851年由法国物理学家阿曼德斐索&#xff08;Armand Fizeau&#xff09;进行的一项重要实验&#xff0c;旨在测量光在移动介质中的传播速度。这项实验的结果对当时的物理理论产生了深远的影响&#xff0c;并且在后来的相…

langchain基础(二)

一、输出解析器&#xff08;Output Parser&#xff09; 作用&#xff1a;&#xff08;1&#xff09;让模型按照指定的格式输出&#xff1b; &#xff08;2&#xff09;解析模型输出&#xff0c;提取所需的信息 1、逗号分隔列表 CommaSeparatedListOutputParser&#xff1a;…

【C语言】static关键字的三种用法

【C语言】static关键字的三种用法 C语言中的static关键字是一个存储类说明符&#xff0c;它可以用来修饰变量和函数。static关键字的主要作用是控制变量或函数的生命周期和可见性。以下是static关键字的一些主要用法和含义&#xff1a; 局部静态变量&#xff1a; 当static修饰…

深度学习-97-大语言模型LLM之基于langchain的实体记忆和知识图谱记忆

文章目录 1 内存记忆Memory1.1 记忆系统支持的操作1.2 记忆的存储1.3 记忆的查询2 记忆的应用2.1 设置环境变量2.2 ConversationEntityMemory实体记忆2.3 ConversationKGMemory知识图谱记忆2.3.1 创建ConversationKGMemory2.3.2 创建ConversationChain2.4 ConversationBufferWi…

AWS Snowball

AWS Snowball 作为一种物理数据迁移设备&#xff0c;不仅仅是提供一种简单的搬运工具&#xff0c;而是为企业在面对大规模数据传输时提供了一种既高效又安全的解决方案。以下是对 AWS Snowball 的详细扩展&#xff0c;帮助你更全面地理解其工作原理和应用场景&#xff1a; 1. 服…

TCP是怎么判断丢包的?

丢包在复杂的网络环境中&#xff0c;是一种常见的现象。 TCP&#xff08;传输控制协议&#xff09;作为一种可靠传输协议&#xff0c;内置了多种机制来检测和处理丢包现象&#xff0c;从而保证数据的完整性和传输的可靠性。本文将介绍TCP判断丢包的原理和机制。 一、TCP可靠传…