Step 4 of 5
Overloading
In C, every function needs a unique name, which leads to families like abs, labs, fabs. C++ allows overloading: several functions can share a name as long as their parameter lists differ (in number or types). The compiler picks the right one from the arguments at each call.
#include <iostream>
#include <string>
std::string describe(bool b) { return b ? "yes" : "no"; }
std::string describe(double d) { return "about " + std::to_string((int)d); }
std::string describe(const std::string& s) { return "'" + s + "'"; }
std::string describe(int a, int b) { return std::to_string(a) + ".." + std::to_string(b); }
int main() {
std::cout << describe(true) << "\n";
std::cout << describe(9.7) << "\n";
std::cout << describe(std::string("hi")) << "\n";
std::cout << describe(1, 5) << "\n";
}
yes
about 9
'hi'
1..5
How the compiler chooses
This is called overload resolution. The compiler looks at the argument types and picks the best match: an exact match beats one that needs a conversion. If two candidates are equally good, the call is ambiguous and doesn't compile, and if none fits, you get "no matching function".
Rules
- The return type alone can't distinguish overloads; the parameters must differ.
- Overloads should do the same kind of thing for different types. If they do unrelated things, give them different names.
- Beware literals:
describe("hi")would pick thebooloverload here, because a string literal converts to a pointer and a pointer converts toboolmore directly than tostd::string. That's why the example passesstd::string("hi").
std::to_string itself is an overloaded function: it has versions for int, long, double and more.
Your turn: write two overloads of describe: one taking an int that returns "int N", and one taking a std::string that returns "string S". Use std::to_string(n) to turn a number into a string.