Namespaces
Variants

Alternative operator representations

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
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
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

C++ (и C) исходный код может быть написан на любом 7-битном наборе символов, не являющемся ASCII, который включает ISO 646:1983 инвариантный набор символов. Однако некоторые операторы и пунктуаторы C++ требуют символов, находящихся за пределами кодового набора ISO 646: {, }, [, ], #, \, ^, |, ~ . Для возможности использования кодировок символов, где некоторые или все эти символы отсутствуют (например, немецкая DIN 66003 ), C++ определяет следующие альтернативы, составленные из совместимых с ISO 646 символов.

Содержание

Альтернативные токены

Существуют альтернативные написания для нескольких операторов и других токенов, которые используют символы не из набора ISO646. Во всех аспектах языка каждый альтернативный токен ведет себя точно так же, как и его основной токен, за исключением написания ( оператор строкификации может сделать написание видимым). Двухбуквенные альтернативные токены иногда называются "диграфами". Несмотря на то, что состоит из четырех символов, % : % : также считается диграфом.

Основной Альтернативный
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
|= or_eq
^ xor
^= xor_eq
{ <%
} %>
[ <:
] :>
# %:
## %:%:

Триграфы (удалены в C++17)

Следующие трёхсимвольные группы (триграфы) обрабатываются до распознавания комментариев и строковых литералов , и каждое появление триграфа заменяется соответствующим основным символом:

Основной Триграф
{ ??<
} ??>
[ ??(
] ??)
# ??=
\ ??/
^ ??'
| ??!
~ ??-

Поскольку триграфы обрабатываются на раннем этапе, комментарий вида // Will the next line be executed?????/ фактически закомментирует следующую строку, а строковый литерал вида "Enter date ??/??/??" будет проанализирован как "Enter date \\ ??" .

Примечания

Символы & и ! являются инвариантными в ISO-646, однако для токенов, использующих эти символы, предусмотрены альтернативы для совместимости с ещё более ограниченными историческими наборами символов.

Для оператора равенства == не существует альтернативного написания (такого как eq ), поскольку символ = присутствовал во всех поддерживаемых наборах символов.

Совместимость с C

Те же самые слова определены в языке программирования C в заголовочном файле <iso646.h> как макросы. Поскольку в C++ они встроены в язык, C++ версия <iso646.h> , а также <ciso646> , не определяет ничего. Однако не-словесные диграфы (например < % ) являются частью базового языка и могут использоваться без подключения каких-либо заголовочных файлов (в противном случае они были бы непригодны для использования в любых кодировках, где отсутствует # ).

Ключевые слова

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

Пример

Следующий пример демонстрирует использование нескольких альтернативных токенов.

%:include <iostream>
struct X
<%
    compl X() <%%> // destructor
    X() <%%>
    X(const X bitand) = delete; // copy constructor
    // X(X and) = delete; // move 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:>);
    else
        greet("Anon");
%>

Возможный вывод:

Hello Anon from ./a.out

Ссылки

  • Стандарт C++23 (ISO/IEC 14882:2024):
  • 5.5 Альтернативные токены [lex.digraph]
  • Стандарт C++20 (ISO/IEC 14882:2020):
  • 5.5 Альтернативные токены [lex.digraph]
  • Стандарт C++17 (ISO/IEC 14882:2017):
  • 5.5 Альтернативные токены [lex.digraph]
  • Стандарт C++14 (ISO/IEC 14882:2014):
  • 2.4 Триграфные последовательности [lex.trigraph]
  • 2.6 Альтернативные токены [lex.digraph]
  • Стандарт C++11 (ISO/IEC 14882:2011):
  • 2.4 Триграфные последовательности [lex.trigraph]
  • 2.6 Альтернативные токены [lex.digraph]
  • Стандарт C++03 (ISO/IEC 14882:2003):
  • 2.3 Триграфные последовательности [lex.trigraph]
  • 2.5 Альтернативные токены [lex.digraph]
  • Стандарт C++98 (ISO/IEC 14882:1998):
  • 2.3 Триграфные последовательности [lex.trigraph]
  • 2.5 Альтернативные токены [lex.digraph]

Смотрите также

C documentation for Alternative operators and tokens