用户定义字面量(UDL)是C++11引入的特性,通过operator""_后缀形式在全局或命名空间中定义以下划线开头的自定义后缀函数,支持整数、浮点、字符串、字符等字面量类型,实现类型安全与可读性提升。

用户定义字面量(User-Defined Literals,UDL)是 C++11 引入的特性,允许你为字面量添加自定义后缀(比如 123_km、"hello"_s),并绑定到一个特殊的 operator 函数上,从而实现类型安全、可读性强的字面量构造。
基本语法:operator "" 后缀名
UDL 的声明形式固定为:operator "" _后缀名,必须在全局作用域或命名空间内定义,不能是成员函数。后缀名必须以下划线开头(如 _km、_s),这是强制规定,避免与标准库或未来标准冲突。
它不是重载运算符,而是一个独立的函数名;编译器在遇到 值_后缀 时,会尝试匹配对应参数类型的 operator "" _后缀 函数。
支持的参数类型和常见用法
UDL 函数的参数取决于字面量类型,编译器会自动传递解析后的值或字符序列:
立即学习“C++免费学习笔记(深入)”;
-
整数字面量(如
42_km)→ 参数为unsigned long long -
浮点字面量(如
3.14_rad)→ 参数为long double -
字符串字面量(如
"abc"_s)→ 参数为const char*+std::size_t(长度) -
字符字面量(如
'x'_tag)→ 参数为char、wchar_t等单个字符类型
示例:定义一个把千米转成米的 UDL:
constexpr int operator"" _km(unsigned long long val) {
return static_cast(val * 1000);
}
// 使用:auto d = 5_km; // d == 5000
字符串 UDL:支持编译期处理(C++14 起更友好)
字符串字面量 UDL 接收 const char* 和长度,但原始字符数组不保证空终止,且 C++11 中无法直接用 constexpr 处理变长字符串。常用技巧是包装成 std::string_view(C++17)或自定义字符串类。
C++14 起允许字面量运算符模板,支持任意长度字符串的编译期解析(需配合字符数组模板参数):
templateconstexpr auto operator"" _sv() { return std::integer_sequence {}; } // 更实用的写法(C++17): constexpr std::string_view operator"" _sv(const char* s, size_t n) { return std::string_view{s, n}; } // 使用:"hello"_sv → string_view,零开销
注意事项和限制
- 后缀名必须以下划线开头,否则编译错误
- 不能定义在类内部;不能是 static 或 inline(除非 C++17 允许 inline constexpr UDL)
- 函数必须有返回值,且不能是 void
- 若多个 UDL 匹配(如同时定义了
int和long long版本),编译器按字面量类型精确匹配,不进行隐式转换 - 推荐使用
constexpr,便于编译期计算和优化
基本上就这些。写 UDL 的关键是选对参数类型、加好下划线、返回有意义的类型——它不是炫技工具,而是提升接口清晰度和类型安全的实用机制。









