The specificity of the overload of the post increment and decrement operators
Tags: cpp, beginners
Published: 2023-03-10 13:09:09

---
title: The specificity of the overload of the post increment and decrement operators
published: true
description: How to differenciate between the post and pre increment/decrement operator while overloading them?
tags: [cpp, beginners]
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sytf1uqgu7fknz1bfuuk.png
---

## Article::Article
In C++ as in many language, you can use the `++` or `--` operators to increment or decrement a variable representing a number. It can be placed before the variable, in the case this is the prefix operator also called postfix operators, or after, then it is a postix operator also called suffix operators.
```C++
int i = 0;
// Pre increment
++i;
// Post increment
i++
// Pre decrement
--i;
// Post decrement
i--
```
![Tuxedo poo meme in 3 panels. First is i = 1 + 1, second is i +=1 and third is i++](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sytf1uqgu7fknz1bfuuk.png)

## The difference between those operators
The first, and well known, difference, aside from the fact that one is placed before and the other is placed after, if that the prefix operators will be executed before the rest of the expression and the postfix operators will be executed after.

Here's a little example to see it better:
```C++
#include <iostream>

int main()
{
    int i = 0;
    std::cout << ++i << std::endl; // Print 1
    std::cout << i++ << std::endl; // Also print 1
    std::cout << i << std::endl; // Print 2
}
```
[Compiler explorer link](https://godbolt.org/z/ne6a6snK1)

Note: don't do this because it is undefined behavior:
```C++
// Examples taken from cppreference
// https://en.cppreference.com/w/cpp/language/eval_order
i = ++i + i++;     // undefined behavior
i = i++ + 1;       // undefined behavior
i = ++i + 1;       // undefined behavior
++ ++i;            // undefined behavior
f(++i, ++i);       // undefined behavior
f(i = -1, i = -1); // undefined behavior

f(i, i++); // undefined behavior
a[i] = i++; // undefined bevahior
```


The second one is that for the built-in versions of theses operators, the pre increment operator directly increment the variable and returns a reference, but for the post decrement operator, it makes a copy, increment it and then return it. Usually when overloading an operator, people tends to keep it the same way and that's why some people will argue that the pre increment operator is more optimized. But when overloading it, it is totally possible to take a reference as parameter instead of a copy, and also if the type is trivial, all compilers optimize it with only the `-O1` flag. You can see it on compiler explorer: [here the unoptimized version](https://godbolt.org/z/8vhfxMznE) and [here the optimized version](https://godbolt.org/z/oq6vWev83).

## Overload
### The pre increment operators
That's the easiest one, here's how to do it:

```C++
struct Int
{
    // Overload it as a member function
    Int& operator++()
    {
        ++i;
        return *this;
    }

    int i;
};

// Overload it as free Function
Int& operator--(Int& fi)
{
    --fi.i;
    return fi;
}
```
[Compiler Explorer link](https://godbolt.org/z/38E36nea8)

### The post increment operators
It is done the example same way, but you add an integer argument. This argument is only used to differentiate both overloads, its value will always be 0.

```C++
struct Int
{
    // Overload it as a member function
    Int operator++(int)
    {
        ++i;
        return *this;
    }

    int i;
};

// Overload it as free Function
Int operator--(Int fi, int)
{
    --fi.i;
    return fi;
}
```
[Compiler Explorer link](https://godbolt.org/z/cfs1Ynda1)

## The chaotic usage
When I said just above the value of the integer for the postfix operator will always be 0, that's not exactly true, if you use the operator overload like a regular function like this, it can have a value:
```C++
#include <iostream>

struct Int
{
    // Overload it as a member function
    Int operator++(int n)
    {
        i += --n;
        return *this;
    }

    int i;
};

// Overload it as free Function
Int operator--(Int fi, int n)
{
    fi.i -= ++n;
    return fi;
}

int main()
{
    Int i{5};
    auto other_i = i.operator++(5);

    std::cout << other_i.i << std::endl; // 5 + 5 -1 = 9
}
```
[Compiler Explorer link](https://godbolt.org/z/f8z4hv3sv)

I hope that nobody is really doing this.

## Article::~Article
The increment and decrement operators have no secrets for you anymore. You know what they do, how to use them and how to overload them.

## Sources
* [https://en.cppreference.com/w/cpp/language/operator_incdec](https://en.cppreference.com/w/cpp/language/operator_incdec)
* [https://en.cppreference.com/w/cpp/language/eval_order](https://en.cppreference.com/w/cpp/language/eval_order)