代用运算符表示
C++(及 C)源代码可以用任何包含 ISO 646:1983 不变字符集的非 ASCII 7 位字符集书写。然而,一些 C++ 运算符及标点要求 ISO 646 编码集外的字符:{,},[,],#,\,^,|,~
。为了能够使用不存在一些或全部这些符号的字符编码(例如德语 DIN 66003),C++ 定义下列由 ISO 646 兼容字符组成的代用写法。
代用记号
几个使用非 ISO-646 字符的运算符和其他记号都有代用拼写。在语言的所有方面,各个代用拼写都严格与其首选记号的表现相同,除了其拼写(字符串化运算符能使拼写可见)。双字母代用记号有时被称为“双标符 (digraphs)”。尽管有四个字母,%:%: 也被当作双标符。
首选 | 代用 |
---|---|
&&
|
and |
&=
|
and_eq |
&
|
bitand |
|
|
bitor |
~
|
compl |
!
|
not |
!=
|
not_eq |
||
|
or |
|=
|
or_eq |
^
|
xor |
^=
|
xor_eq |
{ |
<%
|
} |
%>
|
[ |
<:
|
] |
:>
|
# |
%:
|
## |
%:%:
|
三标符 (C++17 中移除)
下列三字符组(三标符,trigraph)在辨识注释和字符串字面量之前被分析,而三标符的每次出现都会被替换成对应的首选字符:
首选 | 三标符 |
---|---|
{ |
??<
|
} |
??>
|
[ |
??(
|
] |
??)
|
# |
??=
|
\ |
??/
|
^ |
??'
|
| |
??!
|
~ |
??-
|
因为三标符的处理非常早,所以像 // Will the next line be executed?????/ 这样的注释实际上会注释掉下一行(编译时加上 -Wcomment 命令会对此警告),而如 "Enter date ??/??/??" 这样的字符串字面量将被分析为 "Enter date \\??"。
注解
字符 & 及 ! 在 ISO-646 下不变,但仍然为使用这些字符的记号提供了代用写法,以便能够适应更加受限的历史字符集。
没有相等运算符 == 的代用拼写(如 eq),因为字符 = 已在所有受支持字符集中存在。
与 C 的兼容性
C 编程语言中,同样的单词作为宏在包含文件 <iso646.h> 中定义。因为 C++ 中它们在语言中内建,所以 <iso646.h> 的 C++ 版本还有 <ciso646> 不定义任何内容。不过,非单词的双标符(如 <%)是核心语言的一部分,无需包含任何头文件即可使用(否则的话,它们就无法在缺少 # 的任何字符集下使用了)。
关键词
and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq
示例
以下示例演示各种代用记号的使用。
%:include <iostream> struct X <% compl X() <%%> // 析构函数 X() <%%> X(const X bitand) = delete; // 复制构造函数 // X(X and) = delete; // 移动构造函数 bool operator not_eq(const X bitand other) <% return this not_eq bitand other; %> %>; int main(int argc, char* argv<::>) <% // 带引用捕获的 lambda auto greet = <:bitand:>(const char* name) <% std::cout << "Hello " << name << " from " << argv<:0:> << '\n'; %>; if (argc > 1 and argv<:1:> not_eq nullptr) greet(argv<:1:>); else greet("Anon"); %>
可能的输出:
Hello Anon from ./a.out
引用
- C++23 标准(ISO/IEC 14882:2024):
- 5.5 Alternative tokens [lex.digraph]
- C++20 标准(ISO/IEC 14882:2020):
- 5.5 Alternative tokens [lex.digraph]
- C++17 标准(ISO/IEC 14882:2017):
- 5.5 Alternative tokens [lex.digraph]
- C++14 标准(ISO/IEC 14882:2014):
- 2.4 Trigraph sequences [lex.trigraph]
- 2.6 Alternative tokens [lex.digraph]
- C++11 标准(ISO/IEC 14882:2011):
- 2.4 Trigraph sequences [lex.trigraph]
- 2.6 Alternative tokens [lex.digraph]
- C++03 标准(ISO/IEC 14882:2003):
- 2.3 Trigraph sequences [lex.trigraph]
- 2.5 Alternative tokens [lex.digraph]
- C++98 标准(ISO/IEC 14882:1998):
- 2.3 Trigraph sequences [lex.trigraph]
- 2.5 Alternative tokens [lex.digraph]