Deleting Functions

#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;
}