---
title: "16.7 Operator overloading with std::ops"
description: "Every operator is a trait: implementing Add, Mul, Index, and Neg for your own types, one lesson where C++ needs a whole chapter."
url: "https://learnrust.net/chapter-16/operator-overloading/"
last_updated: "2026-06-13"
---

# 16.7 Operator overloading with std::ops

Here's a small revelation that captures the whole chapter. When you write `3 + 4`, the `+` is calling a method of a trait named `Add`. Every operator in Rust, `+`, `-`, `*`, `[]`, unary `-`, works this way: it's syntax for a trait method. Which means **operator overloading**, making `+` work on your own types, isn't a special feature at all. It's just implementing a trait, the same skill you've used for `Summary` and `Display`. This lesson is one page; the C++ chapter it replaces is sixteen lessons, and the difference is exactly because Rust didn't make operators special.

## + is the Add trait

The operator traits live in `std::ops`. Addition is `Add`, and implementing it for your type makes `+` work on it:

```rust
use std::ops::Add;

#[derive(Debug, Clone, Copy)]
struct Point {
    x: f64,
    y: f64,
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Point) -> Point {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

fn main() {
    let a = Point { x: 1.0, y: 2.0 };
    let b = Point { x: 3.0, y: 4.0 };
    println!("{:?}", a + b);
}
```

```
Point { x: 4.0, y: 6.0 }
```

`a + b` calls `add(a, b)` under the hood, because we implemented `Add` for `Point`. The implementation has two parts: `type Output = Point` declares what type the addition produces (an **associated type**, the trait saying "implementers specify what `+` returns"), and `fn add` defines the operation, here adding the points componentwise. Once this exists, `+` on two `Point`s is as ordinary as `+` on two numbers, because for numbers it was always this same trait.

> **Key insight**
>
> Operators in Rust are syntax sugar for trait methods: `a + b` is `Add::add(a, b)`, `a * b` is `Mul::mul(a, b)`, `a[i]` is `Index::index(a, i)`. This is why "operator overloading" needs no dedicated feature, no special rules, no separate chapter. It falls out of traits for free. The same mechanism that let you add a `summarize` method lets you add a `+` operator, because to Rust they're the same kind of thing.

## The other operator traits

Each operator maps to a trait in `std::ops`, and implementing it follows the same pattern. A sampling:

`Mul` is `*` (with `type Output` and `fn mul`), so you could scale a `Point` by a number. `Sub` is `-`, `Div` is `/`, `Rem` is `%`. `Neg` is the *unary* minus, so `-point` works:

```rust
use std::ops::Neg;

impl Neg for Point {
    type Output = Point;
    fn neg(self) -> Point {
        Point { x: -self.x, y: -self.y }
    }
}
```

`Index` is the `[]` indexing operator, letting `collection[i]` work on your own type (it's how `Vec` and `HashMap` support `[]`, lessons [18.2](https://learnrust.net/chapter-18/vec-creating-and-updating/) and [18.6](https://learnrust.net/chapter-18/hashmap/)). `AddAssign` is `+=`, `MulAssign` is `*=`, and so on for the compound-assignment operators (lesson [6.3](https://learnrust.net/chapter-6/compound-assignment/)). The pattern never changes: find the trait for the operator in `std::ops`, implement its one method, and the operator works on your type.

## When to overload, and when not to

A power this clean is easy to misuse. The guiding rule: overload an operator only when its meaning is *obvious and conventional* for your type. Adding two `Point`s componentwise is obvious; everyone reading `a + b` for points expects exactly that. Defining `+` to mean "concatenate these two database records" is not obvious, and a reader will be misled by the familiar symbol. The whole value of an operator is that it carries a shared expectation; overloading it to mean something surprising squanders that.

> **Best practice**
>
> Implement operator traits only when the operator's standard meaning maps cleanly onto your type: arithmetic on math-like types (vectors, points, money, matrices), indexing on collection-like types. If you find yourself writing a comment to explain what `+` does on your type, it shouldn't be `+`, make it a named method instead. Clear method names beat clever operators whenever the operator's meaning isn't instantly obvious.

## The C++ comparison, stated outright

This lesson is deliberately short, and that brevity is the point. C++ treats operator overloading as a major topic: separate rules for member versus non-member operators, friend functions, return-by-value versus reference, the assignment operators, the subscript operator, conversion operators, a whole chapter's worth. Rust has one uniform answer for all of it: operators are traits, implement the trait. There's nothing to learn here beyond "which trait is which operator," because you already know how to implement a trait. That collapse, sixteen lessons into one, is the clearest single illustration of why a Rust course can be shorter than a C++ one without covering less.

## Quiz time

**Question #1**

When you write `a + b`, what is actually being called, and what does that imply about operator overloading?

<details class="solution">
<summary>Show solution</summary>

`a + b` calls the `add` method of the `Add` trait: `Add::add(a, b)`. So operators are syntax for trait methods, which means "overloading" an operator is just implementing the corresponding trait for your type. There's no special operator-overloading feature; it falls out of traits.

</details>

**Question #2**

What two parts does an `impl Add for Point` need, and what does each do?

<details class="solution">
<summary>Show solution</summary>

`type Output = ...`, an associated type declaring what type the `+` produces (e.g. `Point`), and `fn add(self, other: Point) -> Point`, the method defining the actual operation. The `Output` type lets the trait support operators that return a different type than their operands; `add` does the work.

</details>

**Question #3**

Should you implement `Add` to concatenate two unrelated records? Why or why not?

<details class="solution">
<summary>Show solution</summary>

No. Overload an operator only when its conventional meaning maps obviously onto your type (componentwise addition of points, scaling, indexing collections). `+` meaning "concatenate records" is surprising, and a reader seeing `a + b` will expect arithmetic, not that. When the meaning isn't instantly obvious, use a named method instead. The operator's value is its shared expectation.

</details>

Operators are conversions of a sort, turning operands into a result. The next lesson covers actual conversions, the `From` and `Into` traits, which pay off lesson [4.10](https://learnrust.net/chapter-4/numeric-conversions/)'s IOU about the "blessed" way to convert between types and reveal how the `?` operator quietly converts error types.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
