Modern C++字面量一网打尽

C++ Literals

数值

二进制、八进制、十六进制字面量

  • 二进制:0b0B开头。
  • 八进制:0开头。
  • 十六进制:0x0X开头。
cpp 复制代码
// for different base
constexpr int base2 = 0b1111;  // 二进制 15
constexpr int base8 = 017;     // 8进制 15
constexpr int base10 = 15;     // 十进制 15
constexpr int base16 = 0xf;    // 16进制 15
// 检查
static_assert(base2 == 15);
static_assert(base8 == 15);
static_assert(base10 == 15);
static_assert(base16 == 15);

单引号作为数值分隔符

C++14 引入了单引号作为数值分隔符,可以提高可读性。

cpp 复制代码
// ' separator for digit grouping
constexpr int a = 1'000'000;  // 1000000, 十进制
static_assert(a == 1000000);

// 同样适用于其他进制单位
constexpr int c = 0b1'0000;  // 16, 二进制
static_assert(c == 16);

constexpr int d = 01'0000;  // 4096, 八进制
static_assert(d == 4096);

constexpr int b = 0x1'0000;  // 65536, 十六进制
static_assert(b == 65536);

修饰存储类型

  • uU:表示无符号整数(unsigned)。
  • lL:表示长整型(long)。
  • llLL:表示长长整型(long long)。
  • z:表示带符号的std::size_t
cpp 复制代码
// 修饰存储类型
#include <type_traits>
auto si = 1;  // int, 默认
static_assert(std::is_same_v<decltype(si), int>);

auto ui = 1u;  // unsigned int
static_assert(std::is_same_v<decltype(ui), unsigned int>);

auto ul = 1ul;  // unsigned long
static_assert(std::is_same_v<decltype(ul), unsigned long>);

auto ull = 1ull;  // unsigned long long
static_assert(std::is_same_v<decltype(ull), unsigned long long>);

auto l = 0l;  // long
static_assert(std::is_same_v<decltype(l), long>);

auto ll = 0ll;  // long long
static_assert(std::is_same_v<decltype(ll), long long>);

auto z = 0z;  // from C++23, 带符号的 std::size_t
static_assert(std::is_same_v<decltype(z), std::ptrdiff_t>);

auto uz = 0uz;  // from C++23
static_assert(std::is_same_v<decltype(uz), std::size_t>);
#include <vector>
void sample(std::vector<int>& vec) {
  // uz 的另外一个用法, 如果不加后缀会出现无符号数和有符号数的比较警告
  for (auto i = 0uz; i < vec.size(); ++i) {
    // do something
  }
  // 逆序遍历
  for (auto i = vec.size(); i--;) {
    // do something
  }
}

浮点数字面量修饰符:

  • fF:表示float类型。
  • lL:表示long double类型。
cpp 复制代码
// 修饰浮点数
auto f = 1.0f;  // float
static_assert(std::is_same_v<decltype(f), float>);
auto d = 1.0;  // double, 默认
static_assert(std::is_same_v<decltype(d), double>);
auto ld = 1.0l;  // long double
static_assert(std::is_same_v<decltype(ld), long double>);

科学计数法

cpp 复制代码
// 科学计数法
constexpr double e = 1e3;  // 1000.0
static_assert(e == 1000.0);
constexpr auto E = 1E3;  // 1000.0
static_assert(E == 1000.0);

字符字面量

字符字面量修饰符:

  • u:表示一个UTF-16字符(char16_t类型)。
  • U:表示一个UTF-32字符(char32_t类型)。
  • L:表示一个宽字符(wchar_t类型)。
  • u8:表示一个UTF-8字符(char类型)。
cpp 复制代码
// 修饰字符
auto c = 'a';  // char, 默认
static_assert(std::is_same_v<decltype(c), char>);

auto wc = L'汉';  // wchar_t
static_assert(std::is_same_v<decltype(wc), wchar_t>);

auto u8c = u8'a';  // char8_t
static_assert(std::is_same_v<decltype(u8c), char8_t>);

auto u = u'a';  // char16_t
static_assert(std::is_same_v<decltype(u), char16_t>);

auto U = U'a';  // char32_t
static_assert(std::is_same_v<decltype(U), char32_t>);

字符串字面量

原始字符串字面量

对于多行字符串,可以使用原始字符串字面量,这样就不需要转义字符了。

cpp 复制代码
// 原始字符串字面量
auto json = R"({"key": "value"})";
static_assert(std::is_same_v<decltype(json), const char*>);

std::string 字面量

C++14 引入了std::string字面量,可以直接使用字符串字面量初始化std::string对象。

cpp 复制代码
// std::string 字面量
#include <string>
using namespace std::string_literals;  // C++14
auto str = "hello"s;                   // 注意这里的 s
static_assert(std::is_same_v<decltype(str), std::string>);

utf-8 字符串字面量

C++17 引入了utf-8字符串字面量,可以直接使用utf-8字符串字面量初始化std::string对象。

cpp 复制代码
// utf-8 字符串字面量
auto utf8 = u8"你好";
static_assert(std::is_same_v<decltype(utf8), const char*>);

其他字面量

布尔字面量

cpp 复制代码
// 布尔字面量
auto boolean = true;  // bool, 默认
static_assert(std::is_same_v<decltype(boolean), bool>);
auto b2 = false;  // bool
static_assert(std::is_same_v<decltype(b2), bool>);

空指针字面量

cpp 复制代码
// 空指针字面量
auto null = nullptr;  // std::nullptr_t, 默认
static_assert(std::is_same_v<decltype(null), std::nullptr_t>);

用户定义的字面量(User-Defined Literals, UDL)

C++11 引入了用户定义的字面量(User-Defined Literals, UDL),允许程序员为自定义类型定义自己的字面量表示。这通过定义一个字面量运算符实现,运算符以 _ 开头,后跟一个或多个字符。

以下是一个简单的例子,定义一个用于表示长度的用户定义字面量:

cpp 复制代码
#include <iostream>

// 定义一个表示长度的结构体
struct Length {
  double value; // 长度值
  enum Unit { meter, kilometer, centimeter }; // 单位
  Unit unit; // 长度单位

  // 构造函数
  Length(double val, Unit u) : value(val), unit(u) {}
};

// 用户定义的字面量,用于米
Length operator"" _m(long double val) {
  return Length(val, Length::meter);
}

// 用户定义的字面量,用于千米
Length operator"" _km(long double val) {
  return Length(val, Length::kilometer);
}

// 用户定义的字面量,用于厘米
Length operator"" _cm(long double val) {
  return Length(val, Length::centimeter);
}

int main() {
  Length length1 = 10.0_m; // 10米
  Length length2 = 5.0_km; // 5千米
  Length length3 = 100.0_cm; // 100厘米

  std::cout << "Length1: " << length1.value << " meters\n";
  std::cout << "Length2: " << length2.value << " kilometers\n";
  std::cout << "Length3: " << length3.value << " centimeters\n";

  return 0;
}

源码

完整的样例在这里.

相关推荐
Theodore_10222 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
‘’林花谢了春红‘’4 小时前
C++ list (链表)容器
c++·链表·list
----云烟----4 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024065 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it5 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康5 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
机器视觉知识推荐、就业指导6 小时前
C++设计模式:建造者模式(Builder) 房屋建造案例
c++
宅小海6 小时前
scala String
大数据·开发语言·scala