字面量类型由后缀和上下文共同决定:整数如123默认为int(若可容纳),123ULL强制为unsigned long long;浮点如1.0为double、1.0f为float;字符串字面量类型是const char[N],非std::string;UDL后缀须以下划线开头且函数需constexpr;nullptr类型为std::nullptr_t。

字面量的类型由后缀和上下文共同决定
不加修饰的数字字面量,比如 123、3.14,类型不是“默认 int”或“默认 double”——C++ 标准只规定了最小保证范围,具体类型取决于字面量形式和编译器实现。例如:123 是 int(如果 int 能容纳),但 1234567890123 在 32 位系统上就可能是 long long;123U 明确是 unsigned int,而 123ULL 强制为 unsigned long long。
浮点字面量同理:1.0 是 double,1.0f 是 float,1.0L 是 long double。漏写 f 可能在 float 比较中引发隐式转换和精度丢失,比如 float x = 0.1; 实际存储的是近似值,而 0.1f == 0.1 为 false(后者是 double)。
字符串字面量的类型是 const char[N],不是 std::string
写 "hello" 得到的是一个以 \0 结尾的字符数组,类型为 const char[6](含终止符)。它不能直接赋给 std::string 变量而不触发构造(虽然语法允许,那是调用了隐式构造函数),更不能赋给 char*(C++11 起禁止非 const 转换)。
-
const char* p = "hello";✅ 合法 -
char* p = "hello";❌ 编译错误(弃用的转换) -
std::string s = "hello";✅ 调用std::string(const char*)构造 -
auto s = "hello";→s类型是const char[6],不是std::string
多行字符串必须用反斜杠续行或用原始字符串字面量:R"(line1\nline2)",否则 "line1\nline2" 中的换行会破坏语法。
立即学习“C++免费学习笔记(深入)”;
用户定义字面量(UDL)要小心返回类型和求值时机
定义像 123_km 这样的字面量,本质是调用一个带特定后缀名的 constexpr 函数。它必须满足:参数类型只能是 unsigned long long、long double、const char*、char、wchar_t 等有限几种,且函数必须是 constexpr 才能用于常量表达式。
十天学会易语言图解教程用图解的方式对易语言的使用方法和操作技巧作了生动、系统的讲解。需要的朋友们可以下载看看吧!全书分十章,分十天讲完。 第一章是介绍易语言的安装,以及运行后的界面。同时介绍一个非常简单的小程序,以帮助用户入门学习。最后介绍编程的输入方法,以及一些初学者会遇到的常见问题。第二章将接触一些具体的问题,如怎样编写一个1+2等于几的程序,并了解变量的概念,变量的有效范围,数据类型等知识。其后,您将跟着本书,编写一个自己的MP3播放器,认识窗口、按钮、编辑框三个常用组件。以认识命令及事件子程序。第
constexpr long long operator"" _km(unsigned long long val) {
return static_cast(val * 1000);
}
// 使用
constexpr auto d = 5_km; // ✅ 编译期计算
int x = 5_km; // ✅ 运行时也行,但失去 constexpr 优势
常见陷阱:
- 后缀名必须以 underscore 开头(如
_km),否则编译失败 - 返回类型若不是字面量类型(如含非静态成员的类),就不能用于
constexpr上下文 - 字符串 UDL(
operator"" _s(const char*, size_t))参数是裸指针 + 长度,不带终止符,别直接当 C 字符串用
布尔和空指针字面量没有歧义,但要注意模板推导
true 和 false 类型固定为 bool,不会退化成整数;nullptr 类型是 std::nullptr_t,专用于指针比较,比 NULL(常定义为 0 或 ((void*)0))更安全。
但在模板函数中,nullptr 的类型推导可能出人意料:
templatevoid f(T) { } f(nullptr); // T 推导为 std::nullptr_t,不是 void* f(0); // T 推导为 int
所以重载函数里区分指针和整数时,void f(std::nullptr_t) 比 void f(void*) 更精准;而用 auto 推导时,auto p = nullptr; 得到的是 std::nullptr_t,不是指针类型,不能解引用。
字面量看着简单,但类型细节一旦错位,轻则隐式转换带来性能损耗,重则模板匹配失败或 constexpr 场景编译不过。最易被忽略的是字符串字面量的数组类型本质,以及 UDL 后缀命名规则和 constexpr 约束。









