C++ Function Overloading
In C++, several functions may have the same name if their parameters differ in number or type. This is function overloading. The compiler looks at the arguments of each call and picks the matching version.
Overloads by type
#include <iostream>
#include <string>
int twice(int x) { return x * 2; }
double twice(double x) { return x * 2; }
std::string twice(const std::string& s) { return s + s; }
int main() {
std::cout << twice(21) << "\n";
std::cout << twice(1.25) << "\n";
std::cout << twice(std::string("ha")) << "\n";
return 0;
}42 2.5 haha
Without overloading, these would need three names such as twiceInt, twiceDouble and twiceString. With it, the caller writes twice and the right version is chosen.
Overloads by number of parameters
#include <iostream>
int area(int side) { return side * side; } // square
int area(int width, int height) { return width * height; } // rectangle
int main() {
std::cout << "square: " << area(4) << "\n";
std::cout << "rectangle: " << area(4, 3) << "\n";
return 0;
}square: 16 rectangle: 12
What counts as different
Overloads must differ in their parameters. Two functions that differ only in their return type are not allowed: int f() and double f() cannot both exist, because a call f() would not tell which one is meant.
Ambiguous calls
If an argument fits two overloads equally well, the compiler reports an ambiguous call. For example, with void show(long) and void show(double), the call show(5) is ambiguous: the int 5 converts to both. Fix it by calling with the exact type (show(5L)) or by adding an int overload. Default arguments can cause the same problem: area(int) together with area(int, int = 1) makes area(4) ambiguous.
Overloading and templates
When several overloads do exactly the same thing for different types, a template (see Templates) writes the code once for all types. Overloading is the right tool when the versions really differ, such as area for a square and a rectangle.
Overloading in the standard library
You use overloading all the time: std::cout << has an overload for every basic type, and std::to_string has one for int, long, double and more. Your own types can join in by overloading operators (see Operator Overloading).
Practice exercises
- Write
printoverloads forint,doubleandboolthat print the value and its kind. - Write
maximumoverloads for two and for three integers. - Create an ambiguous call on purpose and read the error.