首页 > 编程语言 >C++ 用户自定义字面量(operator"" _)

C++ 用户自定义字面量(operator"" _)

时间:2023-03-25 17:35:53浏览次数:46  
标签:1024 return 字面 自定义 unsigned long constexpr C++ operator

目录

字面量

字面量是指源码中,固定的常量。比如,

const char* p = "abcd";
const std::string s = "efg";
const int v = 10;
const double d = 20.1;
const unsigned long l = 123465789ul;

等式右边的值,就称为字面量。其中,"abcd","efg"称为字符串字面量,10称为整数字面量,20.1称为浮点数字面量,123465789ul称为无符号长整数字面量。
等式左边变量,是字面量赋值给对应变量的名称。

自定义字面量

定义容量字面量

假设我们想以1byte为基础,为单位KB, MB, GB, TB, ... ,定义字面量。如果按传统C方式,我们可能需要这样做:

#define BYTE 1
#define KB (1024 * BYTE)
#define MB (1024 * KB)
#define GB (1024 * MB)
#define TB (static_cast<long long>(1024) * GB)

我们知道宏宏虽然速度快,但不安全,因此将其改写成C++风格:

constexpr int BYTE() 
{
    return 1;
}
constexpr int KB()
{
    return 1024 * BYTE();
}
constexpr int MB()
{
    return 1024 * KB();
}
constexpr int GB()
{
    return 1024 * MB();
}
constexpr long long TB()
{
    return static_cast<long long>(1024) * GB();
}

现在有个问题,就是如果我们想要以4KB为基础单位,怎么办?
比如,我们想一次性为一个数组分配4KB大小的存储单元。

std::array<char, 4 * KB()> buf;

能不能把4*放到函数KB()里面?
答案是可以的。C++ 11给了我们更多选择,可以使用operator""实现用户自定义字面量。其用法特点:operator"" _ 标识符,双引号后必须以"_"开头命名的标识符名;如果需要重载,可以传入参数。

constexpr unsigned long long operator"" _KB(unsigned long long k)
{
  return k * 1024;
}
constexpr unsigned long long operator"" _MB(unsigned long long m)
{
  return m * 1024 * 1024;
}
constexpr unsigned long long operator"" _GB(unsigned long long g)
{
  return g * 1024 * 1024 * 1024;
}
constexpr unsigned long long operator"" _TB(unsigned long long g)
{
  return g * 1024 * 1024 * 1024 * 1024;
}

现在,当我们想分配4KB大小数组时,可以这样做:

std::array<char, 4_KB> buf;

定义时间字面量

再比如,我们可以为时间单位,小时、分钟、秒,定义自定义字面量,用户可以指定具体是多少小时、多少分钟、多少秒,程序无需重新定义类型(函数)。

constexpr std::chrono::hours operator"" _h(unsigned long long h)
{
  return std::chrono::hours(h);
}
constexpr std::chrono::minutes operator"" _min(unsigned long long min)
{
  return std::chrono::minutes(min);
}
constexpr std::chrono::seconds operator"" _s(unsigned long long s)
{
  return std::chrono::seconds(s);
}
constexpr std::chrono::milliseconds operator"" _ms(unsigned long long ms)
{
  return std::chrono::milliseconds(ms);
}

使用时,可以这样表示一天:

constexpr auto OFFSET = 24_h;

这样做的好处:
1)使用函数能进行类型检查,比宏更安全;
2)将单位的运算放在operator函数内部,而不是用户定义处,用户使用起来更方便,不容易写错。

参考

https://github.com/aria2/aria2 (aria2源码)
https://blog.csdn.net/m0_71009069/article/details/128772813
https://zhuanlan.zhihu.com/p/434508865

标签:1024,return,字面,自定义,unsigned,long,constexpr,C++,operator
From: https://www.cnblogs.com/fortunely/p/17255183.html

相关文章

  • C++ 2023年计算机学院”新生杯“ACM天梯赛周赛(一) 二进制转化的感悟
    题目描述对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:0000000001000100001100100请按从小到大的顺序输出这32种01......
  • 如何在Android Studio中创建自定义图标
    今天学习时发现了一个很棒的功能,那就是在AndroidStudio中创建自定义图标,我们在开发app时,常需要用到一些图标,我们当然可以去网上公共素材库找,但是大小什么的往往不尽......
  • c++ linux 编译 静态库 ,动态库
                        一起编译:  静态路径要用全路径    静态编译       规范写法  ......
  • linux c++编译
                gcc-v查看版本                     指定名字    多文件编译 ......
  • c++的内存补齐
    数据类型占用的字节数:char1short2int4longlong8当我们需要进行内存补齐的时候,是看最大类型然后进行补齐。structtest{shorta;shortb;c......
  • 【C++】类与对象理解和学习(中)
    六大默认成员函数前言每个类中都含有六大默认成员函数,也就是说,即使这个类是个空类,里面什么都没有写,但是编译器依然会自动生成六个默认成员函数,可以说它们六个是祖师爷钦点的......
  • C++餐厅点餐结算系统[2023-03-25]
    C++餐厅点餐结算系统[2023-03-25]题目某餐馆根据实际需要欲开发一套《餐厅点餐结算系统》,具体要求如下:1、系统用户包括消费者、收银员、厨师、服务员、餐厅老板、系统......
  • c++union用法
    参考文章:c++中union的使用  union使用方法union即为联合,它是一种特殊的类。通过关键字union进行定义,一个union可以有多个数据成员。在任意时刻,联合中只能有一个数据成......
  • Android 自定义View 之 Mac地址输入框
    Mac地址输入框前言正文一、什么是View?二、什么是自定义View三、自定义View①构造方法②XML样式③测量④绘制1.绘制方框2.绘制文字⑤输入1.键盘布局2.键盘接口3.......
  • element-plus的el-dialog对话框组件自定义样式未生效
    修改dialog组件样式必须在非scoped环境下,再加一个style标签,并给需要加的dialog一个类名eg:createDialog<stylelang="scss"scoped>...</style><stylelang="scss">.crea......