Function overloading allows you to define multiple functions with the same name but different parameters.
int add(int x, int y) // integer version
{
return x + y;
}
double add(double x, double y) // floating point version
{
return x + y;
}
Overload resolution is the process of determining which overloaded function to call based on the arguments provided.
void deg_min_sec2decimal(double deg, double min, double sec, double& dec_deg)
{
dec_deg = (deg + min / 60.0 + sec / 3600.0);
}
foo(0); // int can be numerically converted to unsigned int or to float
foo(3.14159); // double can be numerically converted to unsigned int or to float
// ambiguous result causes error
You can delete specific overloads to prevent them from being used.
void printInt(char) = delete; // calls to this function will halt compilation
void printInt(bool) = delete; // calls to this function will halt compilation
template <typename T>
void printInt(T x) = delete;
void printInt(int x)
{
std::cout << x << '\n';
}
printInt(97); // okay
printInt('a'); // compile error
printInt(true); // compile error
Functions can have parameters with default arguments.
void print(int x, int y = 10) // 10 is the default argument
{
std::cout << "x: " << x << '\n';
std::cout << "y: " << y << '\n';
}
print(1, 2); // y will use user-supplied argument 2
print(3); // y will use default argument 10
Note: If a parameter is given a default argument, all subsequent parameters must also be given default arguments.
#ifndef FOO_H
#define FOO_H
void print(int x, int y = 4);
#endif
template <typename T> // this is the template parameter declaration
T max(T x, T y) // this is the function template definition for max<T>
{
return (x < y) ? y : x;
}
std::cout << max<int>(1, 2) << '\n'; // calls max<int>(int, int)
std::cout << max<>(1, 2) << '\n'; // deduces max<int>(int, int)
std::cout << max(1, 2) << '\n'; // calls max(int, int)
template <typename T>
int someFcn(T, double){} // Template parameter and double
#ifndef ADD_H
#define ADD_H
template <typename T>
T addOne(T x) // function template definition
{
return x + 1;
}
#endif
auto max(auto x, auto y)
{
return (x < y) ? y : x;
}
#include <iostream>
template <int N> // declare a non-type template parameter of type int named N
void print()
{
std::cout << N << '\n'; // use value of N here
}
print<5>(); // 5 is our non-type template argument
template <typename T>
struct Pair
{
T first{};
T second{};
};
template <typename T>
constexpr T max(Pair<T> p)
{
return (p.first < p.second ? p.second : p.first);
}
Pair<int> p1{ 5, 6 };
Pair<double> p2{ 1.2, 3.4 };
std::cout << max(p2) << '\n'; // call to max<double> using template argument deduction
std::cout << max<int>(p1) << '\n'; // explicit call to max<int>
template <typename T, typename U>
struct Pair
{
T first{};
U second{};
};
template <typename T, typename U>
void print(Pair<T, U> p)
{
std::cout << '[' << p.first << ", " << p.second << ']';
}
Pair<int, double> p1{ 1, 2.3 }; // a pair holding an int and a double
print(p1);
#include <utility> // for std::pair
std::pair p1{ 1, 2 }; // CTAD used to deduce std::pair<int, int> from the initializers (C++17)
std::pair p2 { 3.4f, 5.6f }; // deduced to pair<float, float>
std::pair p3 { 1u, 2u }; // deduced to pair<unsigned int, unsigned int>
Pair p4; // uses default Pair<int, int>
template <typename T>
using Coord = Pair<T>; // Coord is an alias for Pair<T>
Coord<int> p1 { 1, 2 }; // Pre C++-20: We must explicitly specify all type template arguments
Coord p2 { 1, 2 }; // In C++20, we can use alias template deduction to deduce the template arguments in cases where CTAD works
// Here's a deduction guide for our Pair (needed in C++17 only)
template <typename T, typename U>
Pair(T, U) -> Pair<T, U>;