_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
# [Getting started in C++](/) - [Operators](/notebooks/3-Operators/0-main.ipynb) - [Introduction](/notebooks/3-Operators/1-Intro.ipynb)
# [Getting started in C++](/) - [Operators](./0-main.ipynb) - [Introduction](./1-Intro.ipynb)
%% Cell type:markdown id: tags:
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#Motivation"data-toc-modified-id="Motivation-1">Motivation</a></span></li><li><span><ahref="#Overloading-an-operator"data-toc-modified-id="Overloading-an-operator-2">Overloading an operator</a></span></li><li><span><ahref="#Operator-between-different-types"data-toc-modified-id="Operator-between-different-types-3">Operator between different types</a></span></li><li><span><ahref="#Limitations"data-toc-modified-id="Limitations-4">Limitations</a></span></li><li><span><ahref="#Conversion-operators"data-toc-modified-id="Conversion-operators-5">Conversion operators</a></span></li></ul></div>
%% Cell type:markdown id: tags:
## Motivation
We've seen at length in the object programming part that classes are basically new types defined by the developer. However sometimes we would like to use exactly the same syntax as for the base type. Let's see for instance a basic class to handle tri-dimensional vectors:
%% Cell type:code id: tags:
``` C++17
class Vector
{
// Friendship because `Add()` needs to access private members and no accessors were defined.
Now the same with a _plain old data type_ is much more natural to write with no (apparent) method:
%% Cell type:code id: tags:
``` C++17
{
double x1 = 3.;
double x2 = 7.;
double x3 = x1 + x2;
std::cout << x3 << std::endl;
}
```
%% Cell type:markdown id: tags:
C++ provides the way to mimic this behaviour with **operator overloading**. This is a very powerful conceit, but also one that should be approached with some care...
We will see the general way to define such an operator in this notebook and see in dedicated notebooks which are the ones specifically useful.
## Overloading an operator
To overload an operator, the syntax is just the keyword **operator** followed by the operator to overload.
%% Cell type:code id: tags:
``` C++17
class Vector2
{
public :
Vector2(double x, double y, double z);
Vector2() = default;
void Print() const;
// I would rather put the definition outside but Xeus-cling doesn't seem to accept this.
We see in the definition of the operator+ that both `Vector2` added aren't symmetric: one is the data attribute while the other is the data attribute of an object given as an argument.
As a side note, please remark the `operator+` implementation is able to reach the private data attributes of the argument `v`; this means the private status is set **at class level** and not at object level.
It is actually possible to define the operator as a free function, thus providing a more symmetric implementation:
**Xeus-cling issue**: cling doesn't accept operator definition outside of class; please use [@Coliru](https://coliru.stacked-crooked.com/a/626efa4fb6a02915):
If you want it to be possible, you have to define the operator with arguments in both orders; you therefore need to use out-of-class prototype of the function (can't show it currently due to Xeus-cling limitation).
Of course, if you do so you should define one in way of the other:
* The precedence rules (between `+` and `*` for instance)
You can't _invent_ new operators, but only redefine operators in the following list (that might be incomplete: I learnt about `""` operator very recently on [this blog post](https://www.fluentcpp.com/2016/12/08/strong-types-for-strong-interfaces/)):
````
+ - * / % ^ & | ~ !
= < > += -= *= /= %= ^= &=
|= << >> >>= <<= == != <= >= &&
|| ++ -- ->* , -> [] () new delete
""
````
(plus **conversion operators** - see next section).
If not defined, some of them exist by default:
````
=
. -> .* ->*
new delete sizeof
-> ->*
new delete
````
Some can never be redefined:
````
: :: . .* ? ?: sizeof
````
## Conversion operators
A conversion operator is a method of transforming an object into a given type. When the compiler needs to force the type of an object, implicitly or explicitly, it is this operator that will be called. A conversion operator is required for each type of conversion.
%% Cell type:code id: tags:
``` C++17
#include <iostream>
class Rational
{
public :
Rational(int numerator, int denominator);
operator int() const;
operator double() const;
private :
int numerator_ = 0;
int denominator_ = 0;
};
```
%% Cell type:code id: tags:
``` C++17
Rational::Rational(int numerator, int denominator)
_This notebook is an adaptation of a lecture prepared by David Chamont (CNRS) under the terms of the licence [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)](http://creativecommons.org/licenses/by-nc-sa/4.0/)_
_The present version has been written by Sébastien Gilles and Vincent Rouvreau (Inria)_
# [Getting started in C++](/) - [Operators](/notebooks/3-Operators/0-main.ipynb) - [Comparison operators](/notebooks/3-Operators/2-Comparison.ipynb)
# [Getting started in C++](/) - [Operators](./0-main.ipynb) - [Comparison operators](./2-Comparison.ipynb)
%% Cell type:markdown id: tags:
<h1>Table of contents<spanclass="tocSkip"></span></h1>
<divclass="toc"><ulclass="toc-item"><li><span><ahref="#Operator-<,->,-<=,->=" data-toc-modified-id="Operator-<,->,-<=,->=-1">Operator <, >, <=, >=</a></span></li><li><span><a href="#Operator-==-and-!="data-toc-modified-id="Operator-==-and-!=-2">Operator == and !=</a></span></li></ul></div>
%% Cell type:markdown id: tags:
## Operator <, >, <=, >=
These 4 operators are **not** implicitly defined for a class (and that is very natural: what would be the rationale to devise the default `<` operator for a `ComplexNumber` or a `Car` class?)
Let's take again our `Rational` class to illustrate this:
**Xeus-cling** issue: cling doesn't accept operator definition outside of class; please use [@Coliru](https://coliru.stacked-crooked.com/a/6f0dc54ac63f476c):
%% Cell type:code id: tags:
``` C++17
// Xeus-cling issue: doesn't compile!
#include <iostream>
class Rational
{
public :
explicit Rational(int numerator, int denominator);
explicit operator double() const;
private :
int numerator_ = 0;
int denominator_ = 0;
};
Rational::Rational(int numerator, int denominator)