DEV Community

Cover image for The specificity of the overload of the post increment and decrement operators
Lena
Lena

Posted on

The specificity of the overload of the post increment and decrement operators

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.

int i = 0;
// Pre increment
++i;
// Post increment
i++
// Pre decrement
--i;
// Post decrement
i--
Enter fullscreen mode Exit fullscreen mode

Tuxedo poo meme in 3 panels. First is i = 1 + 1, second is i +=1 and third is i++

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:

#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
}
Enter fullscreen mode Exit fullscreen mode

Compiler explorer link

Note: don't do this because it is undefined behavior:

// 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
Enter fullscreen mode Exit fullscreen mode

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 and here the optimized version.

Overload

The pre increment operators

That's the easiest one, here's how to do it:

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;
}
Enter fullscreen mode Exit fullscreen mode

Compiler Explorer link

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.

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;
}
Enter fullscreen mode Exit fullscreen mode

Compiler Explorer link

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:

#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
}
Enter fullscreen mode Exit fullscreen mode

Compiler Explorer link

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

Top comments (0)