C++20 STL CookBook2 更强大的编译时 + 安全比较 + spaceship比较符

embedded/2024/11/8 23:24:31/

目录

使用编译时vector和字符串相关的上下文变量

安全的比较整数

<=> :)


使用编译时vector和字符串相关的上下文变量

在大部分C语言程序中,我见过不少人是这样使用常量字符串的:

#define STR "Hello, C++"

然后可能传递进入一些函数做一些可能跟字符串本身存储字符无关的运算。但是C++中,除非控制编译流程,实在不建议使用宏。那有没有代替品呢?有!我们可以使用一些编译时就可以确定的东西传递:

#include <iostream>
static constexpr const char* ready_calc = "string";
constexpr size_t gain_const_string() {return std::string(ready_calc).size();
}

或者:

constexpr auto check_sum(){std::vector<int> vec{1, 2, 3, 4, 5};return std::accumulate(std::begin(vec), std::end(vec), 0);
}

constexpr 说明符声明可在编译时求值的变量或函数。在 C++20 之前,这仅限于用文字值初始化的对象或有限约束内的函数。C++17 允许稍微扩展用途,而 C++20 进一步扩展了它。从 C++20 开始,STL 字符串和向量类现在具有 constexpr 限定的构造函数和析构函数,允许在编译时调用它们。这也意味着必须在编译时释放为字符串或向量对象分配的内存。

安全的比较整数

典中典例子:

int x{ -3 };
unsigned y{ 7 };
if(x < y) puts("true");
else puts("false");

它会打印 false。

问题是 x 是有符号的,而 y 是无符号的。标准化行为是将有符号类型转换为无符号以进行比较。这似乎违反直觉,不是吗?事实上,将无符号值转换为相同大小的有符号值,因为有符号整数使用二进制补码表示法(使用最高有效位作为符号)。给定相同大小的整数,最大有符号值是无符号值的一半。使用此示例,如果整数是 32 位,-3(有符号)将变为 FFFF FFFD(十六进制),或 4,294,967,293(无符号十进制),不小于 7。

这下看懂,那有没有办法避免这种抽象错误呢?有:

#include <utility>
int main() {int x{ -3 };unsigned y{ 7 };if(cmp_less(x, y)) puts("true");else puts("false");
}

这个玩意好说:实际上就是模板转化一下:

template< class T, class U >
constexpr bool cmp_less( T t, U u ) noexcept
{using UT = make_unsigned_t<T>;using UU = make_unsigned_t<U>;if constexpr (is_signed_v<T> == is_signed_v<U>)return t < u;else if constexpr (is_signed_v<T>)return t < 0 ? true : UT(t) < u;elsereturn u < 0 ? false : t < UU(u);
}

<=> :)

Spaceship运算符!哈哈,这个东西用来化简比较运算符的

三向比较的工作方式不同。它返回三种状态之一。如果操作数相等,宇宙飞船运算符将返回等于 0 的值;如果左侧操作数小于右侧操作数,则返回负值;如果左侧操作数大于右侧运算符,则返回正值。

 const int a = 7; const int b = 42; static_assert((a <=> b) < 0); 

返回的值不是整数。它是 <compare> 标头中的一个对象,与 0 进行比较。 如果操作数具有整数类型,则运算符从 <compare> 库中返回一个 strong_ordering 对象。

  • strong_ordering::equal // 操作数相等

  • strong_ordering::less // lhs 小于 rhs

  • strong_ordering::greater // lhs 大于 rhs

如果操作数具有浮点类型,则运算符返回 partial_ordering 对象:

  • partial_ordering::equivalent // 操作数相等

  • partial_ordering::less // lhs 小于 rhs

  • partial_ordering::greater // lhs 大于 rhs

  • partial_ordering::unordered // 如果操作数无序

这些对象旨在使用常规比较运算符(例如,(a <=> b) < 0)与文字零 (0) 进行比较。这使得三向比较的结果比传统比较更精确。 如果这一切看起来有点复杂,那没关系。它的真正威力在于它作为对象的统一比较运算符的应用。

当然还可以自己定义:

struct Frac {long n;long d;constexpr Frac(int a, int b) : n{a}, d{b} {}constexpr double dbl() const {return static_cast<double>(n) / static_cast<double>(d);}constexpr auto operator<=>(const Frac& rhs) const {return dbl() <=> rhs.dbl();};constexpr auto operator==(const Frac& rhs) const {return dbl() <=> rhs.dbl() == 0;};
};

http://www.ppmy.cn/embedded/136014.html

相关文章

ORACLE _11G_R2_ASM 常用命令

--------查看磁盘组&#xff0c;(空间情况) select name,state,free_mb,total_mb,usable_file_mb from v$asm_diskgroup; --------查看磁盘情况 select GROUP_NUMBER,free_mb,total_mb,disk_number,MOUNT_STATUS,mode_status, HEADER_STATUS,name,PATH from v$asm_disk order …

window10解决 docker is starting 问题

win10 需要开启 Hyper-V。 在程序和功能中开启服务Server (不开启的话&#xff0c;安装完会报错) 安装toolbox 最新版 Toolbox 下载地址&#xff1a; 访问 https://www.docker.com/get-started&#xff0c;注册一个账号&#xff0c;然后登录。 点击 Get started with Docke…

vue3 + vite引入地址路径报错,以及无法点击跳转相应的文件

vue3 vite引入地址路径报错&#xff0c;以及无法点击跳转相应的文件 在项目中找到tsconfig.json&#xff0c;或者jsconfig.json 文件&#xff0c;使用一下代码替换即可。如果两个文件都不存在&#xff0c;如果项目使用了ts&#xff0c;就创建tsconfig.json文件&#xff0c;复…

【系统配置】信创终端操作系统如何彻底禁用ssh _ 统信 _ 麒麟 _ 方德

原文链接&#xff1a;【系统配置】信创终端操作系统如何彻底禁用ssh | 统信 | 麒麟 | 方德 Hello&#xff0c;大家好啊&#xff01;今天带来一篇关于如何在信创终端操作系统中彻底禁用SSH的文章。在某些安全性要求较高的环境中&#xff0c;禁用SSH服务可以防止未经授权的远程访…

单细胞 RNA 测序分析的当前最佳实践:教程-文献精读80

Current best practices in single‐cell RNA‐seq analysis: a tutorial 单细胞 RNA 测序分析的当前最佳实践&#xff1a;教程 摘要 单细胞 RNA 测序使基因表达的研究达到了前所未有的分辨率。这项技术的前景吸引了越来越多的用户使用单细胞分析方法。随着更多分析工具的出现…

C++11的简介

杀马特主页&#xff1a;羑悻的小杀马特.-CSDN博客 ------ ->欢迎阅读 欢迎阅读 欢迎阅读 欢迎阅读 <------- 目录 一列表初始化的变化&#xff1a; 二左右值即各自引用的概念&#xff1a; 2.1左右…

蓝桥杯c++算法学习【1】之枚举与模拟(卡片、回文日期、赢球票:::非常典型的比刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 枚举与模拟 一、卡片&#xff1a; 【问题描述】 …

如何在算家云搭建CodeGeeX4(文本生成)

一、 大模型 CodeGeeX4 简介 CodeGeeX4 模型系列的开源版本 CodeGeeX4-ALL-9B。它是一个在 GLM-4-9B 上持续训练的多语言代码生成模型&#xff0c;显著增强了其代码生成能力。使用单个 CodeGeeX4-ALL-9B 模型&#xff0c;它可以支持代码补全和生成、代码解释器、网页搜索、函数…