10.13 — Deleting functions

In some cases, it is possible to write functions that don’t behave as desired when called with values of certain types.

Consider the following example:

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

This example prints:

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 compile error.

Here’s an updated version of the above making use of this 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
    printInt(true); // compile error
    
    return 0;
}

Although you can delete a non-overloaded function, there typically is no reason to, as that function wouldn’t be called in the first place.

For advanced readers

Other types of functions can be similarly deleted.

We discuss deleting member functions in lesson 14.14 -- Introduction to the copy constructor, and deleting function template specializations in lesson 10.16 -- Function template instantiation.

Deleting all non-matching overloads Advanced

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. We can do this by using a function template (introduced in upcoming lesson 10.15 -- Function templates as follows:

#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;
}
guest
Your email address will not be displayed
Find a mistake? Leave a comment above!
Correction-related comments will be deleted after processing to help reduce clutter. Thanks for helping to make the site better for everyone!
Avatars from https://gravatar.com/ are connected to your provided email address.
Notify me about replies:  
8 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments