#include <iostream>
void printInt(int x)
{
std::cout << x << '\n';
}
int main()
{
printInt(5); // okay: prints 5
printInt('a'); // prints 97 -- does this make sense?
printInt(true); // print 1 -- does this make sense?
return 0;
}
// Output
5
97
1
While printInt(5)
is clearly okay, the other two calls to printInt()
are more questionable. With printInt('a')
, the compiler will determine that it can promote a
to int value 97
in order to match the function call with the function definition. And it will promote true
to int value 1
. And it will do so without complaint.
Let's assume we don't think it makes sense to call printInt()
with a value of type char
or bool
. What can we do?
Deleting a function using the = delete
specifier
In cases where we have a function that we explicitly do not want to be callable, we can define that function as deleted by using the = delete
specifier. If the compiler matches a function call to a deleted function, compilation will be halted with a compilation error.
Here's an updated version of the above making use of the syntax:
#include <iostream>
void printInt(int x)
{
std::cout << x << '\n';
}
void printInt(char) = delete; // calls to this function will halt compilation
void printInt(bool) = delete; // calls to this function will halt compilation
int main()
{
printInt(97); // okay
printInt('a'); // compile error: function deleted
printInt(true); // compile error: function deleted
printInt(5.0); // compile error: ambiguous match
return 0;
}
Let's take a quick look at some of these. First, printInt('a')
is a direct match for printInt(char)
, which is deleted. The compiler thus produces a compilation error. printInt(true)
is a direct match for printInt(bool)
, which is deleted, and thus also produces a compilation error.
Deleting all non-matching overloads
Deleting a bunch of individual function overloads works fine, but can be verbose. There may be times when we want a certain function to be called only with arguments whose types exactly match the function parameters.
#include <iostream>
// This function will take precedence for arguments of type int
void printInt(int x)
{
std::cout << x << '\n';
}
// This function template will take precedence for arguments of other types
// Since this function template is deleted, calls to it will halt compilation
template <typename T>
void printInt(T x) = delete;
int main()
{
printInt(97); // okay
printInt('a'); // compile error
printInt(true); // compile error
return 0;
}