最近在看 CPP 的一些东西的时候,发现了一个非常有意思的特性。不得不说,CPP 的特性总是朝着一些奇奇怪怪的方向发展,整出了一堆奇奇怪怪的语法糖
这个特性叫 User-defined literals
非常简单的一种特性,例如很多时候我们会用一些结构体来表示内存/磁盘等大小,比如这种
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| static size_t B = 1; static size_t KB = 1000 * B; static size_t MB = 1000 * KB; static size_t GB = 1000 * MB; static size_t KiB = 1024 * B; static size_t MiB = 1024 * KiB; static size_t GiB = 1024 * MiB;
struct Size { size_t value; };
inline std::ostream& operator<<(std::ostream& o, const Size& size) { if (size.value < KiB) o << size.value << 'B'; else if (size.value < MiB)o << std::fixed << std::setprecision(2) << 1.0 * size.value / KiB << "KiB"; else if (size.value < GiB)o << std::fixed << std::setprecision(2) << 1.0 * size.value / MiB << "MiB"; else o << std::fixed << std::setprecision(2) << 1.0 * size.value / GiB << "GiB"; return o; }
|
这样就可以有一个表示占用大小的类型了,但是这样并不方便,因为初始化的时候还需要明确表示这个类型。但是用上这个特性之后就可以非常简单,只需要再定义几个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| inline Size operator ""_B(unsigned long long v) { return {v * B}; }
#pragma region 1000
inline Size operator ""_KB(const unsigned long long v) { return {v * KB}; }
inline Size operator ""_MB(const unsigned long long v) { return {v * MB}; }
inline Size operator ""_GB(const unsigned long long v) { return {v * GB}; }
#pragma endregion
#pragma region 1024
inline Size operator ""_KiB(const unsigned long long v) { return {v * KiB}; }
inline Size operator ""_MiB(const unsigned long long v) { return {v * MiB}; }
inline Size operator ""_GiB(const unsigned long long v) { return {v * GiB}; }
#pragma endregion
|
这样之后就可以直接用字面量初始化
1 2
| const auto v = 123435245_KiB; std::cout << v << std::endl;
|