Deleted function in C++


Sign up for FREE 1 month of Kindle and read all our books for free.

Get FREE domain for 1st year and build your brand new site

C++11 introduced a new use of the delete keyword to make a function non-callable.

Introduction

Functions are a set of statements put together that perform a specific task. Member functions include the operators and functions that are members of a class. While the user has to provide these member functions, the compiler generates some of the functions which are known as special member functions.

We may want to disable the use of such functions. The reason may be to restrict certain features (defined by the user) or maybe to suppress a compiler generated member function.

Pre C++11

Prior to C++11, the use of a function could be disabled in many ways such as by

  1. Using accessibility controls
  2. Declaring the function, but intentionally omitting the definition.

The first one is by using accessibility controls such as protected and private which allows us to make a function inaccessible. But this only works for members functions of a class and not for free functions. This is a compile-time check and the errors that result by referencing such a function maybe misleading as access specifiers are used for access restriction and usually not for avoiding use of member functions.
The second one is by only declaring a function and skipping its body, resulting in a link-time diagnostic which are not guaranteed.

The techniques above are far less than perfect since any function should be able to be deleted, including non-member functions. Attempts to use such a deleted function should also result in a compile-time error with a clear diagnostic.

deleted functions

In C++11, a function can be explicitly defined to be deleted. The way to do this is to append a =delete to the end of the function declaration. For example

void foo(int x) =delete;

disables the use of the function foo.

The =delete; is part of the function definition. Thus a function declaration is not deleted but only its use is disabled. A deleted function thus participates in the name lookup and overload resolution. The deleted definition of a function must be its first declaration. This rule prevents inconsistency in interpretation.

Example usage

Eliminate undesired conversions

Consider an example where we disallow float to be converted to an int. If we had not deleted the constructor that accepts a floating point value, a floating point value would be implicitly converted to an int.

#include<iostream>
using namespace std;

struct type{
    int k;
    type(int k):k(k){}
    type(float k)=delete;

    void display(){
        cout << k << endl;
    }
};

int main()
{
    type t(56); // OK
    type t(56.0); // error: use of deleted function
    t.display();

    return 0;
}

Allow a single type

struct type
{
    // ...
    void f(double d);
    template<class T> void f(T) = delete;
};

In the above code, the function f will not accept anything other than a double.

Disable copy assignment and copy construction

The assignment and copying is done by the copy constructors and assignment operators. In C++ these are provided automatically, but, these can be disabled by declaring and appending a =delete.

class B{    
public:
  B(int m): m(m) {}
  B& operator = (const B &) = delete;  // copy assignment operator
  B(const B&) = delete;                // copy constructor

private:
  int m;
};

int main(){
  B b1(1), b2(2), b3(3);
  b1 = b2;             // Error: copy assignment operator is disabled.
  b3 = B(b2);          // Error: copy constructor is disabled.
  
  return 0;
}

Conclusion

Use of =delete allows an explicit way to express as to which of the functions should not used, thus, allows for better diagnostics. It is most useful in restricting unnecessary type conversions and disabling operators.