Why explicitly delete the constructor instead of making it private?

C++

C++ Problem Overview


When/why would I want to explicitly delete my constructor? Assuming the reason is to prevent its usage, why not just make it private?

class Foo
{ 
  public: 
    Foo() = delete; 
};

C++ Solutions


Solution 1 - C++

How about:

//deleted constructor
class Foo
{ 
  public: 
    Foo() = delete;     
  public:
    static void foo();
};

void Foo::foo()
{
   Foo f;    //illegal
}

versus

//private constructor
class Foo
{ 
  private: 
    Foo() {}     
  public:
    static void foo();
};

void Foo::foo()
{
   Foo f;    //legal
}

They're basically different things. private tells you that only members of the class can call that method or access that variable (or friends of course). In this case, it's legal for a static method of that class (or any other member) to call a private constructor of a class. This doesn't hold for deleted constructors.

Sample here.

Solution 2 - C++

why explicitly delete the constructor?

Another reason:
I use delete when I want to assure that a class is called with an initializer. I consider it as a very elegant way to achieve this without runtime checks.

The C++ compiler does this check for you.

class Foo
{
   public:
       Foo() = delete;
       Foo(int bar) : m_bar(bar) {};
   private:
       int m_bar;
}

This - very simplified - code assures that there is no instantiation like this: Foo foo;

Solution 3 - C++

I've met with default ctors declared as 'deleted' in the source code of LLVM (in AlignOf.h for instance). The associated class templates are usually in a special namespace called 'llvm::detail'. The whole purpose there I think was that they considered that class only as a helper class. They never intended to instantiate them; only to use them within the context of other class templates with some metaprogramming tricks that run in compile time.

Eg. there's this AlignmentCalcImpl class template which is used only within another class template called AlignOf as a parameter for the sizeof(.) operator. That expression can be evaluated in compile time; and there's no need to instantiate the template -> so why not declare the default ctor delete to express this intention.

But it's only my assumption.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionashView Question on Stackoverflow
Solution 1 - C++Luchian GrigoreView Answer on Stackoverflow
Solution 2 - C++Peter VARGAView Answer on Stackoverflow
Solution 3 - C++gybacsiView Answer on Stackoverflow