Alternative operator representations

From cppreference.com
< cpplrm; | language
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function declaration
inline specifier
Exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
decltype (C++11)
auto (C++11)
alignas (C++11)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Implicit conversions - Explicit conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous
Expressions
General
value categories (lvalue, rvalue, xvalue)
order of evaluation (sequence points)
constant expressions
unevaluated expressions
primary expressions
lambda-expression(C++11)
Literals
integer literals
floating-point literals
boolean literals
character literals including escape sequences
string literals
null pointer literal(C++11)
user-defined literal(C++11)
Operators
Assignment operators: a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
Increment and decrement: ++a, --a, a++, a--
Arithmetic operators: +a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
Logical operators: a||b, a&&b, !a
Comparison operators: a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b(C++20)
Member access operators: a[b], *a, &a, a->b, a.b, a->*b, a.*b
Other operators: a(...), a,b, a?b:c
Default comparisons(C++20)
Alternative representations of operators
Precedence and associativity
Fold expression(C++17)
new-expression
delete-expression
throw-expression
alignof
sizeof
sizeof...(C++11)
typeid
noexcept(C++11)
Operator overloading
Conversions
Implicit conversions
const_cast
static_cast
reinterpret_cast
dynamic_cast
Explicit conversions (T)a, T(a)
User-defined conversion

C++ (and C) source code may be written in any non-ASCII 7-bit character set that includes the ISO 646:1983 invariant character set. However, several C++ operators and punctuators require characters that are outside of the ISO 646 codeset: {, }, [, ], #, \, ^, |, ~. To be able to use character encodings where some or all of these symbols do not exist (such as the German DIN 66003), C++ defines the following alternatives composed of ISO 646 compatible characters.

Alternative tokens

There are alternative spellings for several operators and other tokens that use non-ISO646 characters. In all respects of the language, each alternative token behaves exactly the same as its primary token, except for its spelling (the stringification operator can make the spelling visible). The two-letter alternative tokens are sometimes called "digraphs"

Primary Alternative
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
|= or_eq
^ xor
^= xor_eq
{ <%
} %>
[ <:
] :>
# %:
## %:%:

When the parser encounters the character sequence <:: and the subsequent character is neither : nor >, the < is treated as a preprocessing token by itself and not as the first character of the alternative token <:. Thus std::vector<::std::string> won't be wrongly treated as std::vector[:std::string>.

(since C++11)

Notes

The characters & and ! are invariant under ISO-646, but alternatives are provided for the tokens that use these characters anyway to accomodate even more restrictive historical charsets.

There is no alternative spelling (such as eq) for the equality operator == because the character = was present in all supported charsets.

Compatibility with C

The same words are defined in the C programming language in the include file <iso646.h> as macros. Because in C++ these are built into the language, the C++ version of <iso646.h>, as well as <ciso646>, does not define anything.

Trigraphs (removed in C++17)

The following three-character groups (trigraphs) are parsed before comments and string literals are recognized, and each appearance of a trigraph is replaced by the corresponding primary character:

Primary Trigraph
{ ??<
} ??>
[ ??(
] ??)
# ??=
\ ??/
^ ??'
| ??!
~ ??-

Because trigraphs are processed early, a comment such as // Will the next line be executed?????/ will effectively comment out the following line, and the string literal such as "Enter date??/??/??" is parsed as "Enter date \\??".

Keywords

and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq

Example

The following example demonstrates the use of several alternative tokens.

%:include <iostream>

struct X
<%
    compl X() <%%> // destructor
    X() <%%>
    X(const X bitand) = delete; // copy constructor

    bool operator not_eq(const X bitand other)
    <%
       return this not_eq bitand other;
    %>
%>;

int main(int argc, char* argv<::>) 
<%
    // lambda with reference-capture:
    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:>);
    %>
%>


See also