【C++ Metaprogramming】0. 在C++中实现类似C#的泛型类
两年前,笔者因为项目原因刚开始接触C++,当时就在想,如果C++有类似C#中的泛型限定就好了,能让代码简单许多。我也一度认为:
虽然C++有模板类,但是却没办法实现C#中泛型特有的 where
关键词:
public class Parent { /* ... */ }
public class Child : Parent { /* ... */ }
public class AnotherClass { /* ... */ }public class GenericClass<T> where T : Parent
{public static void DoSomething(T item) { }
}static void Main(string[] args)
{Child c = new Child();AnotherClass a = new AnotherClass();GenericClass<Parent>.DoSomething(c);GenericClass<Child>.DoSomething(c);GenericClass<AnotherClass>.DoSomething(); // --- 报错
}
但实际上,C++通过不仅能做到这部分内容,而且比C#能做的还要更多。而且很多内容甚至是可以在Compile Time就能做到限制的 —— 不用等到代码跑起来,编译的时候就能够告诉你代码哪里有问题。
C++实现这部分功能所涉及到的技术就是 Metaprogramming,直译过来是“元编程”。
我相信 元编程 这个名字对于大多数人来说是没有意义的,就好像我们第一次听到某种深海动物名字一样,它叫什么不重要,重要的是,它是什么。
比如我现在向大家介绍一种深海动物,“须蛸”。如果我不放这个图,“须蛸”这个名字就是没有任何意义的 (放了这图似乎也没多大意义,但是至少你更加信服这个名字不是我瞎编的了)。
所以什么是元编程?
元编程是对代码的编程
元编程英文里的Meta可以认为是“超级”的意思,这里的“超级”应该不是指“能力强过、高过”,亦不是说“凌驾于xxx之上”的意思。
在我个人理解里,Metaprogramming技术本身并非高明于我们平时的普通编程技术,它只是思维方式不一样。但不幸的是,C++的Metaprogramming是一只披着C++语言外皮的“狼”(需要完全用另一套思维逻辑去思考/实现的另一个编程领域),所以笔者认为这也是为什么许多C++用了许多年的人谈到Metaprogramming这个领域时仍噤若寒蝉——因为它们压根不是一个东西,只是恰好语法底层用到的是同一套东西而已——而且在实际工作中你可以完全不使用该内容而写好自己的代码(只不过在某些情况可能要多付出一点体力劳动……不过有Vim在,那也不是什么大问题嘛)。
说到Meta的“超级”的含义,Metaprogramming在我这里十分像优化领域里的Hyperparameter Optimization (超参数优化)里的“Hyper” —— 同样是“超级”的意思,同样的,超参数优化也不是说它本身相较于普通的参数优化有什么更深奥的技术,只不过是Optimization的参数的Optimization,优化参数的优化,所以就用差不多的技术在对不同的目标套了一层。
巧了么不是,Metaprogramming是对普通programming的programming,我觉得起名叫Hyperprogramming也是挺不错的。而且他俩都有一个共同点,那就是特别烧脑,都要在原有的概念上嵌套一层。
好了,说了这么多,那倒底啥是Metaprogramming?下面就举个简单的例子,我们用C#来实现它,简单说说啥是Metaprogramming。
什么是Metaprogramming
现在我们要写个程序,需求是:
能够返回正整数1-5的平方。
普通编程的方法是:
int ReturnSquare(int i) => i * i;
Metaprogramming的方法是:
写一个Console程序,输出一个cs文件:
static void Main(string[] args)
{using var fs = File.Create("d:\square.cs", FileMode.Create);using var sr = new StreamWriter(fs);sr.AppendLine("int ReturnSquare(int i) => i * i");sr.Flush();
}
这就是Metaprogramming。
???
是的,这就是Metaprogramming。
不过这只是最广义上的概念,但这个概念的确如此 —— 用代码去写代码。这个技术就是Metaprogramming。
我们一般说C++的Metaprogramming是指 “使用C++的模版技术来借助编译器在编译时帮我们生成、检查代码”。
笔者这里再插一段,C#也是有模版的,也是需要借助编译器才可以,感兴趣的读者可以自行搜索“C# Text Template”,或者官方链接:
https://learn.microsoft.com/en-us/visualstudio/modeling/code-generation-and-t4-text-templates?view=vs-2022
对于Metaprogarmming的介绍今天就先到这里了,后面有想到的会继续补充,下面的时间留给标题里的内容。
我是被标题吸引的,我要C++实现泛型限定
- 限定
Parent
类
#include <type_traits>class Parent{};
class Child : public Parent{};
class AnotherClass {};namespace hidden {template <bool b, typename T>struct Helper{static void DoSomething(T item) = delete;};template <typename T>struct Helper<true, T>{static void DoSomething(T item){// ...}};
}template <typename T>
using Generic = hidden::Helper<std::is_base_of_v<Parent, T>, T>;int main()
{Child c;AnotherClass a;Generic<Parent>::DoSomething(c);Generic<AnotherClass>::DoSomething(a); // -- 报错
}
- 限定 “类里必须要有Foo函数” 才可使用
// 具备成员函数Foo
class HasFoo
{
public:int Foo();
};// 不具备成员函数Foo,仅有静态函数Foo
class StaticFoo
{
public:static int Foo();
};
// 啥也没有
class NoFoo { };template <typename, typename = void >
struct has_foo_function_member_or_static : false_type {};template <typename T>
struct has_foo_function_member_or_static<T, void_t<decltype(&T::Foo)>> : true_type {};template <typename T>
using has_foo_function_member = std::conditional_t<has_foo_function_member_or_static<T>::value,std::is_member_function_pointer<decltype(&T::Foo)>,false_type>;int main()
{static_assert(has_foo_function_member<HasFoo>::value, "");//static_assert(has_foo_function_member<StaticFoo>::value, ""); // compile time err//static_assert(has_foo_function_member<NoFoo>::value, ""); // compile time errstatic_assert(has_foo_function_member_or_static<HasFoo>::value, ""); // compile time errstatic_assert(has_foo_function_member_or_static<StaticFoo>::value, ""); // compile time err//static_assert(has_foo_function_member_or_static<NoFoo>::value, ""); // compile time err
}
好了我们下次再见。🦀
相关文章:

【C++ Metaprogramming】0. 在C++中实现类似C#的泛型类
两年前,笔者因为项目原因刚开始接触C,当时就在想,如果C有类似C#中的泛型限定就好了,能让代码简单许多。我也一度认为: 虽然C有模板类,但是却没办法实现C#中泛型特有的 where 关键词: public c…...

TDA4VM/VH 芯片 NAVSS0
请从官网下载 TD4VM 技术参考手册,地址如下: TDA4VM 技术参考手册地址 概述 (NAVSS0 的介绍在 TRM 的第10.2章节) NAVSS0 可以看作 MAIN 域的一个复杂外设域,实现如下功能: UDMASS: DMA 管理子系统;MODSS…...

基于springboot的前后端分离的案列(一)
SpringBootWeb案例 前面我们已经讲解了Web前端开发的基础知识,也讲解了Web后端开发的基础(HTTP协议、请求响应),并且也讲解了数据库MySQL,以及通过Mybatis框架如何来完成数据库的基本操作。 那接下来,我们就通过一个案例…...

Docker网络模式详解
文章目录 一、docker网络概述1、docker网络实现的原理1.1 随机映射端口( 从32768开始)1.2 指定映射端口1.3 浏览器访问测试 二、 docker的网络模式1、默认网络2、使用docker run 创建Docker容器时,可以用--net或--network 选项指定容器的网络模式 三、docker网络模式…...

PXE高效批量网络装机
PXE 定义 PXE(预启动执行环境,在操作系统之前运行)是由Intel公司开发的网络引导技术,工作在client /server模式,允许客户机通过网络从远程服务器下载引导镜像,并加载安装文件或者整个操作系统。 具备以下三个优点 1 规模化: 同时…...

YOLOv5+双目实现三维跟踪(python)
YOLOv5双目实现三维跟踪(python) 1. 目标跟踪2. 测距模块2.1 测距原理2.2 添加测距 3. 细节修改(可忽略)4. 实验效果 相关链接 1. YOLOV5 双目测距(python) 2. YOLOV7 双目测距(python&#x…...
ESP8266使用SDK软硬件定时执行函数
1、软件定时 以下接口使用的定时器由软件实现,定时器的函数在任务中被执行。因为任务可能被中断,或者被其他高优先级的任务延迟,因此以下os_timer系列的接口并不能保证定时器精确执行。 注意: ①对于同一个 timer,os…...

ThreadPoolExecutor源码阅读流程图
1.创建线程池 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), def…...
如何通过筛选高质量爬虫IP提升爬虫效率?
前言 对于做数据抓取的技术员来说,如何稳定高效的爬取数据ip库池起到决定性作用,对于爬虫ip池的维护,可以从以下几个方面入手: 目录 一、验证爬虫ip的可用性二、更新爬虫ip池三、维护爬虫ip的质量四、监控爬虫ip的使用情况 一、验…...
C#中定义数组--字符串及数组操作
C#中定义数组–字符串及数组操作 以前用VB的时候经常使用数组,不过C#用习惯后数组基本上用的不多了。 像用List<>,ArrayList,Dirctionary<,>都比较好用。 一、一维: int[] numbers new int[]{1,2,3,4,5,6}; //不…...

嵌入式就业怎么样?
嵌入式就业怎么样? 现在的IT行业,嵌入式是大热门,下面也要来给大家介绍下学习嵌入式之后的发展以及就业怎么样。 首先是好找工作。嵌入式人才目前是处于供不应求的状态中,据权威统计机构统计在所有软件开发类人才的需求中,对嵌入式工程师的…...

用户订阅付费如何拆解分析?看这篇就够了
会员制的订阅付费在影音娱乐行业中已相当普及,近几年,不少游戏厂商也开始尝试订阅收费模式。在分析具体的用户订阅偏好以及订阅付费模式带来的增长效果时,我们常常会有这些疑问: 如何从用户的整体付费行为中具体拆解订阅付费事件…...
智能合约中如何调用其他智能合约
智能合约是区块链技术中的一项关键功能,它可以让开发者编写代码来自动执行一系列的操作,从而实现各种复杂的业务逻辑。在许多应用场景中,一个智能合约可能需要调用另一个智能合约来完成某些任务。本文将介绍智能合约如何调用其他智能合约&…...
python的多任务处理
在现代计算机系统中,多任务处理是一项重要的技术,可以大幅提高程序的运行效率。Python语言提供了多种多任务处理的方式,本文将介绍其中几种常见的方式,包括多进程、多线程和协程。 多进程 进程是计算机中运行程序的实例…...

Vue收集表单数据学习笔记
收集表单数据 v-model双向数据绑定,收集的是input框的value,单选按钮不存在value,就像代码中的男女选项,即使绑定性别v-model“sex”,控制台依然不能接收性别的值,因为没有value值,,…...

Linux搭建GitLab私有仓库,并内网穿透实现公网访问
文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 转载自远控源码文章:Linux搭建GitLab私有仓库,并内网穿透实现公网访问 …...
SpringBoot项目防重复提交注解开发
背景 在实际开发过程中,防重复提交的操作很常见。有细分配置针对某一些路径进行拦截,也有基于注解去实现的指定方法拦截的。 分析 实现原理 实现防重复提交,我们很容易想到就是用过滤器或者拦截器来实现。 使用拦截器就是继承HandlerInt…...

从软件哲学角度谈 Amazon SageMaker
如果你喜欢哲学并且你是一个 IT 从业者,那么你很可能对软件哲学感兴趣,你能发现存在于软件领域的哲学之美。本文我们就从软件哲学的角度来了解一下亚马逊云科技的拳头级产品 Amazon SageMaker,有两个出发点:一是 SageMaker 本身设…...

C++内联函数
目录 一、常规函数和内联函数的对比 二、如何使用 三、内联函数的特性 四、内联函数与宏 五、如何查看内联函数 六、【面试题】 前言-----内联函数是C中为程序运行速度所做的一项该进。常规函数和内联函数之间的主要区别不在于编写方式,而在于C编译器如何将他…...
JAVA大师的秘籍:轻松掌握高质量代码之道
如果你想写出高质量的代码,那掌握编写技巧可是必不可少哦!这不仅能让你的代码变得更加易读易维护,还可以让你的应用程序性能更强、稳定性更高!所以,别怕麻烦,多花些时间和心思在代码上,相信你一定能成为优秀的JAVA开发者! 要想让代码易读易维护、性能稳定,得拿出耐心和…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...