书籍:《ISO/IEC 14882 2014》
说明:以上内容大部分来自腾讯元宝
如何理解以下内容:
9 [Example:
int main() {
L"A" "B" "C"_x; // OK: same as L"ABC"_x
"P"_x "Q" "R"_y;// error: two different ud-suffixes
}
— end example ]
在C++中,用户定义字符串字面量(UD-SL)的相邻连接规则可通过以下要点理解:
1. 基本规则
在翻译阶段6(字符串连接阶段):
- 相邻字符串自动合并:无论是否为UD-SL,相邻字符串字面量会被合并为单一字符串。
- UD-SL后缀被剥离:连接时所有UD-SL的后缀(如
_x
)会被编译器忽略。 - 后缀一致性要求:若参与连接的UD-SL后缀不同,编译报错。
示例解析:
// 合法:所有UD-SL后缀相同(_x)
L"A"_x "B"_x "C"_x → 等效于 L"ABC"_x
// 非法:后缀不一致(_x vs _y)
"P"_x "Q"_y → 错误:无法统一应用后缀
2. 后缀剥离与合并逻辑
- 后缀剥离:在连接过程中,UD-SL的后缀仅作为语义标识,不参与实际字符串内容。
"file"_path + "name"_path → 合并为 "filename"_path(后缀被剥离后重新附加)
- 后缀一致性检查:编译器要求所有参与连接的UD-SL必须具有相同后缀,否则语义冲突。
3. 错误场景分析
"P"_x "Q"_y; // 错误示例
- 问题:
_x
和_y
是不同的UD-SL后缀。 - 编译器行为:
- 剥离后缀后得到原始字符串
"P"
和"Q"
。 - 合并结果为
"PQ"
,但无法确定应附加哪个后缀(_x
或_y
)。 - 因此报错:
error: two different ud-suffixes
。
- 剥离后缀后得到原始字符串
4. 与普通字符串的对比
场景 | 普通字符串(无后缀) | 用户定义字符串(带后缀) |
---|---|---|
相邻连接 | 直接合并(如 "A" "B" → "AB" ) | 合并后保留统一后缀(如 _x ) |
后缀不一致 | 无错误 | 编译错误 |
5. 实际应用建议
- 统一后缀语义:同一场景下所有UD-SL应使用相同后缀(如路径处理统一用
_path
)。 - 避免混合使用:不同功能的UD-SL应通过显式转换或中间变量处理。
- 结合模板扩展:C++11后可使用模板参数包处理多字符序列(需C++20支持)。
6. 设计示例
// 合法:统一后缀 _path
std::string operator""_path(const char* str, size_t len) {
return "/usr/local/" + std::string(str, len);
}
int main() {
auto path = "src"_path "main.cpp"_path; // 合并为 "/usr/local/srcmain.cpp"_path
}
总结
用户定义字符串字面量的相邻连接规则核心在于:
- 后缀剥离:连接时忽略UD-SL后缀。
- 后缀一致性:所有参与连接的UD-SL必须共享相同后缀。
- 语义保留:合并后的结果仍应用原始后缀的语义(如路径拼接)。
这一机制在保证灵活性的同时,避免了语义歧义。