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

(C11) 泛型表达式

文章目录

  • ⭐语法
  • ⭐举例
    • 🚩判断对象类型
    • 🚩判断指针
    • 🚩函数重载
    • 🚩嵌套使用
  • END

⭐语法

Ref: 泛型选择 (C11 起) - cppreference.com

关键词:

  • Generic
  • default
_Generic(控制表达式 , 关联列表)  (C11 起) 

关联列表

  • 类型名:表达式
    • 类型名:任何并非可变修改的完整对象类型(即既非 VLA 亦非指向 VLA 的指针)。
    • 表达式:任何类型和值类别的表达式(除了逗号运算符)
  • default:表达式

控制表达式

  • 任何表达式(除了逗号运算符),若不使用 default 关联,则其类型必须与 类型名 之一兼容。

判定解释

控制表达式 的类型经历左值转换。

只在类型域中进行转换

  • 舍弃顶层 cvr 限定符和原子属性
  • 数组到指针/函数到指针变换
  • 不实例化任何副效应或计算任何值

有类型匹配,若其类型与各关联之一的 类型名 兼容,则解释为冒号后的表达式。

无类型匹配,且提供了 default 关联,则解释为其后的表达式。

注意

关联列表 中的任意二个 类型名 不能指定兼容类型。

使用关键词 default 的关联只能有一个。若不使用 default,且无一 类型名 与控制表达式类型兼容,则程序无法编译。

⭐举例

🚩判断对象类型

_Generic可以判断自定义类型。

cvr限定符对类型识别不受影响。

default不是必须写道最后一个,顺序这方面没有限制。

#include <stdbool.h>
#include <stdio.h>struct Node {};#define get_typename(x)             \_Generic((x),                   \default: "other",           \_Bool: "bool",              \int: "int",                 \char: "char",               \struct Node: "struct Node"  \)int main() {_Bool       b = true;char        c = 'a';const int   i = 10;struct Node node;printf("Type of [_Bool] is %s\n", get_typename(b));printf("Type of [char] is %s\n", get_typename(c));printf("Type of [int] is %s\n", get_typename(i));printf("Type of [struct Node] is %s\n", get_typename(node));
}

🚩判断指针

对指针类型的判断仍然使用。

#include <stdio.h>#define get_pointname(x) \_Generic((x),        \int*: "int*",    \void*: "void*",  \default: "other" \)int main() {int   i  = 0;int*  ip = NULL;void* vp = NULL;printf("Type of [int] is [%s]\n", get_pointname(i));printf("Type of [int*] is [%s]\n", get_pointname(ip));printf("Type of [void*] is [%s]\n", get_pointname(vp));
}

🚩函数重载

可以根据类型指定调用的函数,注意参数个数。

下方代码展示在使用_Generic时,并且直接调用的情况。_Generic((x), default: fun)(x)

#include <math.h>
#include <stdio.h>int default_fun() {printf("Line[%d], Func[%s]\n", __LINE__, __func__);return -1;
}#define sqrt(x)                  \_Generic((x),            \float: sqrtf,        \double: sqrt,        \long double: sqrtl,  \default: default_fun \)(x)int main(void) {int         i  = 4;float       f  = 4.0f;double      d  = 4.0;long double ld = 4.0L;printf("[i] sqrt = %d\n", sqrt(i));printf("[float] sqrt = %f\n", sqrt(f));printf("[double] sqrt = %lf\n", sqrt(d));printf("[long double] sqrt = %Lf\n", sqrt(ld));
}

🚩嵌套使用

由于每次_Generic只能判断一个表达式的类型,因此如果是需要用到多参的话,可以嵌套的使用_Generic

#include <stdio.h>#define add(x, y)                              \_Generic((x),                              \int: _Generic((y),                     \int: (int)(x) + (int)(y),          \default: (int)(x) + (double)(y)    \),                                     \default: _Generic((y),                 \int: (double)(x) + (int)(y),       \default: (double)(x) + (double)(y) \)                                      \)int main() {int    i1 = 10;int    i2 = 20;double d1 = 3.14;double d2 = 2.71;printf("%d + %d = %d\n", i1, i2, add(i1, i2));  // 整数加法printf("%f + %f = %f\n", d1, d2, add(d1, d2));  // 浮点数加法printf("%d + %f = %f\n", i1, d2, add(i1, d2));  // 混合加法
}

END

关注我,学习更多C/C++,算法,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

相关文章:

  • 【ArcGISPro】CSMPlugins文件夹
  • hubilder Android模拟器华为手机连接不上
  • Unity实现首行缩进两个字符
  • Linux管理文本文件002
  • 从了解到掌握 Spark 计算框架(一)Spark 简介与基础概念
  • leetcode题目42
  • 面试二十六、c++语言级别的多线程编程
  • Spring: OncePerRequestFilter
  • Python学习---基于TCP协议的网络通信程序案例
  • BUUCTF-WEB3
  • Python读取Excel表格文件并绘制多列数据的曲线图
  • git二次上传文件夹、文件
  • 列表、元组、字典和集合的区别
  • Llama 3 CPU推理优化指南
  • Kubernetes 文档 / 概念 / 服务、负载均衡和联网 / 服务(Service)
  • JavaScript-如何实现克隆(clone)函数
  • 《深入 React 技术栈》
  • Asm.js的简单介绍
  • Bootstrap JS插件Alert源码分析
  • es6(二):字符串的扩展
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • interface和setter,getter
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • PHP那些事儿
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • rabbitmq延迟消息示例
  • vue--为什么data属性必须是一个函数
  • 代理模式
  • 对超线程几个不同角度的解释
  • 多线程事务回滚
  • 记录一下第一次使用npm
  • 深度解析利用ES6进行Promise封装总结
  • 新手搭建网站的主要流程
  • 因为阿里,他们成了“杭漂”
  • 正则与JS中的正则
  • #if #elif #endif
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (七)Knockout 创建自定义绑定
  • (一)Neo4j下载安装以及初次使用
  • .dwp和.webpart的区别
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net 设置默认首页
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET框架
  • .NET轻量级ORM组件Dapper葵花宝典
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • /etc/skel 目录作用
  • @property python知乎_Python3基础之:property
  • @RequestBody的使用
  • @ResponseBody
  • @Transaction注解失效的几种场景(附有示例代码)
  • [bbk5179]第66集 第7章 - 数据库的维护 03