Programming in C++

Operator Overloading

Gerald Senarclens de Grancy

Purpose of Operator Overloading

Use the built-in C++ operators on own types.

Allow using C++ operators on existing types that do not support them natively.

Related Conventions

C.168 (C: Classes and class hierarchies)
Define overloaded operators in the namespace of their operands

Using Pythonic Syntax in C++

Concatenate two lists in Python

l1 = [1, 2, 3, 4, 5, 6]  # or `list(range(1, 7))`
l2 = [1, 1, 1, 1, 1, 4] # or `[1] * 5 + [4]`
l3 = l1 + l2
print(l3)

Without operator overloading, this syntax is not possible in C++.

Without operator overloading, the following does not work.

#include <iostream>
#include <vector>

int main(void) {
std::vector<int> v1{1, 2, 3, 4, 5, 6};
std::vector<int> v2(5, 1); v2.push_back(4); // {1, 1, 1, 1, 1, 4}
std::vector<int> v3 = v1 + v2; // compiler problem
std::cout << v3 << std::endl; // compiler problem
}

Solution, Part 1: Overload the + Operator

vector<int> operator+(const vector<int>& v1, const vector<int>& v2) {
vector<int> v;
v.insert(end(v), begin(v1), end(v1));
v.insert(end(v), begin(v2), end(v2));
return v;
}

Solution, Part 1: Overload the + Operator

Better to write generic code.

template <class Type>
vector<Type> operator+(const vector<Type>& v1, const vector<Type>& v2) {
vector<Type> v;
v.insert(end(v), begin(v1), end(v1));
v.insert(end(v), begin(v2), end(v2));
return v;
}

Solution, Part 2: Overload the << Operator

template <class Type>
ostream& operator<<(ostream& out, const vector<Type>& v) {
out << '[';
for (const auto& e: v) {
out << e << ", ";
}
out << "\b\b]"; // two backspace characters to overwrite final ", "
return out;
}

Complete Solution

#include <iostream>
#include <vector>

using std::cout, std::endl; // multiple using on same line is C++17
using std::vector;

namespace std { // C.168: define overloaded operators in namespace of operands

template <class Type>
vector<Type> operator+(const vector<Type>& v1, const vector<Type>& v2) {
vector<Type> v;
v.insert(end(v), begin(v1), end(v1));
v.insert(end(v), begin(v2), end(v2));
return v;
}

template <class Type>
ostream& operator<<(ostream& out, const vector<Type>& v) {
out << '[';
for (const auto& e: v) {
out << e << ", ";
}
out << "\b\b]"; // two backspace characters to overwrite final ", "
return out;
}
} // namespace std

int main(void) {
vector<int> v1{1, 2, 3, 4, 5, 6};
vector<int> v2(5, 1); v2.push_back(4); // {1, 1, 1, 1, 1, 4}
cout << v1 << endl;
cout << v2 << endl;
vector<int> v3 = v1 + v2;
cout << v3 << endl;
}

operator_overloading.cpp

Questions
and feedback...