Перегрузка операторов¶
Для типов структур и классов возможно перегрузить ряд операторов и операций. Перегруженный оператор это просто функция внутри класса и структуры, имеющая специальное имя и выполняющая ряд требований. У всех перегруженных операторов и операций тип одного из аргументов должен быть той структуры или того класса, в которой объявлены операция или оператор.
Объявляется перегруженный оператор с использованием ключевого слова op
и имени оператора после него.
struct Int
{
i32 x;
op+( Int& l, Int& r ) : Int // Перегруженный бинарный оператор
{
var Int i{ .x= l.x + r.x };
return i;
}
op-( Int& a ) : Int // Перегруженный префиксный унарный оператор
{
var Int b{ .x= -a.x };
return b;
}
op++( mut this ) // Перегруженная унарная операция
{
++x;
}
op[]( this, i32 y ) : i32 // Перегруженный постфиксный оператор
{
return x * y;
}
}
fn Foo()
{
var Int mut a{ .x= 42 }, b{ .x= 666 };
++a;
auto ab= a + b;
auto minus_b= -b;
var i32 r= a[5];
}
Перегружаемые операторы и операции:
Оператор | тип | Число аргументов | Возвращаемый результат |
---|---|---|---|
- |
префиксный оператор | 1 | любой |
! |
префиксный оператор | 1 | любой |
~ |
префиксный оператор | 1 | любой |
+ |
бинарный оператор | 2 | любой |
- |
бинарный оператор | 2 | любой |
* |
бинарный оператор | 2 | любой |
/ |
бинарный оператор | 2 | любой |
% |
бинарный оператор | 2 | любой |
& |
бинарный оператор | 2 | любой |
| |
бинарный оператор | 2 | любой |
^ |
бинарный оператор | 2 | любой |
>> |
бинарный оператор | 2 | любой |
<< |
бинарный оператор | 2 | любой |
== |
бинарный оператор | 2 | bool |
<=> |
бинарный оператор | 2 | i32 |
[] |
постфиксный оператор | 2 | любой |
() |
постфиксный оператор | 1 и более | любой |
++ |
унарная операция | 1 | void |
-- |
унарная операция | 1 | void |
= |
бинарная операция | 2 | void |
+= |
бинарная операция | 2 | void |
-= |
бинарная операция | 2 | void |
*= |
бинарная операция | 2 | void |
/= |
бинарная операция | 2 | void |
%= |
бинарная операция | 2 | void |
&= |
бинарная операция | 2 | void |
|= |
бинарная операция | 2 | void |
^= |
бинарная операция | 2 | void |
<<= |
бинарная операция | 2 | void |
>>= |
бинарная операция | 2 | void |
Ряд перегруженных операторов вызываются особым образом.
Для ==
и !=
вызывается перегруженный оператор ==
.
Не существует отдельной перегрузки оператора !=
.
Для получения результата !=
результат вызова ==
инвертируется.
Для операторов упорядочивающего сравнения (<
, <=
, >
, >=
) вызывается перегруженный оператор <=>
.
Результат его вызова сравнивается с нулём для получения конечного результата.
Перегруженному оператору <=>
не обязательно возвращать строго -1 или +1 для индикации отношения больше/меньше, важен лишь знак результата.
Постфиксные операторы¶
Особое место занимают постфиксные операторы. У всех них есть требование, чтобы тип первого аргумента был тот же, что у типа структуры или класса, где объявлен этот оператор.
Оператор индексирования []
позволяет обращаться по индексу к структуре или классу, как будто это массив. При этом тип индекса может быть любым.
Это позволяет, например, организовать ассоциативные контейнеры с доступом по ключу с использованием данного оператора.
Оператор вызова ()
позволяет обращаться с структурой или классом подобно функции. Это позволяет, например, реализовывать функциональные объекты.