167

I've been working on some C++ code that a friend has written and I get the following error that I have never seen before when compiling with gcc4.6:

error: use of deleted function

‘GameFSM_<std::array<C, 2ul> >::hdealt::hdealt()’ is implicitly deleted because the default definition would be ill-formed:
uninitialized non-static const member ‘const h_t FlopPokerGameFSM_<std::array<C, 2ul> >::hdealt::h’

Edit: This comes from a part of the code using boost MSM: Boost Webpage

Edit2: There is no = delete() used anywhere in the sourcecode.

Generally speaking, what does this error mean? What should I be looking for when this type of error occurs?

Xeo
  • 129,499
  • 52
  • 291
  • 397
shuttle87
  • 15,466
  • 11
  • 77
  • 106
  • 4
    and the code that you are compiling? – ColWhi May 11 '11 at 15:26
  • I was more just wondering what the error meant? Do I need to post the code for that as well? – shuttle87 May 11 '11 at 15:27
  • 1
    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47417 might help, also are you using boost? – ColWhi May 11 '11 at 15:32
  • 35
    Since this comes up as the first Google match for this type of error - not the case here, but the most usual cause for this kind of error is after you added some custom constructor to a class - as result the compiler ceases creating the default constructor, and if an instance of the class is ever created through the default constructor, this error appears. Just add the default constructor explicitely. – SF. Jul 24 '15 at 10:55

7 Answers7

210

The error message clearly says that the default constructor has been deleted implicitly. It even says why: the class contains a non-static, const variable, which would not be initialized by the default ctor.

class X {
    const int x;
};

Since X::x is const, it must be initialized -- but a default ctor wouldn't normally initialize it (because it's a POD type). Therefore, to get a default ctor, you need to define one yourself (and it must initialize x). You can get the same kind of situation with a member that's a reference:

class X { 
    whatever &x;
};

It's probably worth noting that both of these will also disable implicit creation of an assignment operator as well, for essentially the same reason. The implicit assignment operator normally does members-wise assignment, but with a const member or reference member, it can't do that because the member can't be assigned. To make assignment work, you need to write your own assignment operator.

This is why a const member should typically be static -- when you do an assignment, you can't assign the const member anyway. In a typical case all your instances are going to have the same value so they might as well share access to a single variable instead of having lots of copies of a variable that will all have the same value.

It is possible, of course, to create instances with different values though -- you (for example) pass a value when you create the object, so two different objects can have two different values. If, however, you try to do something like swapping them, the const member will retain its original value instead of being swapped.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • @Jeffry Coffin: The actual error message was posted as an edit, Initial error message posted was only `C++ error: use of deleted function` – Alok Save May 11 '11 at 15:43
  • 1
    @Als: Sorry, I probably should have been explicit that I didn't intend that as an insult or anything on that order, just that what was currently available made it apparent that those answers weren't right. – Jerry Coffin May 11 '11 at 15:47
  • I assume you might be able to help me with my problem here please: http://stackoverflow.com/questions/23349524/using-boostmutex-implicitly-deleted-error-because-the-default-definition-wo – Saher Ahwal Apr 28 '14 at 19:25
  • "This is why a const member should *typically* be static" - interesting, I've not come across this before. So, idiomatically, if my class has some property that should never change in its lifetime, rather than `const` on construction it should just be `private`, with no non-`const` `public` interface that touches it? – OJFord Mar 19 '15 at 00:19
  • 2
    @OllieFord: That depends. What should happen if (for example) you assign an object with one value in that field to another that has a different value in that field? If it should be overwritten, then it can't be const. If that shouldn't be allowed at all, then the value might really be part of the type (e.g., a template parameter, if known at compile time). – Jerry Coffin Mar 19 '15 at 00:49
  • The key for me here was that operator= was also implicitly deleted. The compiler reported it, but I missed it until rereading this answer. – Cliff Jan 02 '20 at 21:15
  • @JerryCoffin why your answer starts with: The error message clearly says that the default constructor has been deleted implicitly. Clearly people don't understand why, C/C++ are awful languages (nowadays) with encrypted messages, which experience programmer on those languages can understand. Instead of saying that, try to modify open source projects or tools to show better information no errors. – titusfx Oct 24 '20 at 11:52
  • I say it because, at least to me: `hdealt::hdealt()’ is implicitly deleted because the default definition would be ill-formed` seems to be pretty explicit. I don't see how anybody could claim that was "encrypted" or anything similar. If you have an actual suggestion about how to make it more clear I'd be happy to hear it, but as it stands right now you seem to be demanding that I go do a bunch of work to fix something that I'm not convinced is broken, to meet some requirement I don't know or understand, seemingly motivated solely by gratuitous insults. – Jerry Coffin Oct 24 '20 at 18:19
  • @JerryCoffin I am so sorry here is one feedback asked from __stack overflow__ and it asking `is this answer is outdated or not ?` I want to click on `not` but by mistaken I click on `yes`. now here no option to change my feedback. sorry, because your answer is very helpful to me. so just consider my apology. – Abhishek Mane May 19 '21 at 14:51
12

You are using a function, which is marked as deleted.
Eg:

int doSomething( int ) = delete;

The =delete is a new feature of C++0x. It means the compiler should immediately stop compiling and complain "this function is deleted" once the user use such function.

If you see this error, you should check the function declaration for =delete.

To know more about this new feature introduced in C++0x, check this out.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 9
    Out of curiosity, when would doing something like that be helpful? – Pepe May 11 '11 at 15:30
  • @Peter: to prevent implicit conversions. – R. Martinho Fernandes May 11 '11 at 15:31
  • 10
    Actually it says *"implicitly deleted because ..."*, the above example would be explicit. – Georg Fritzsche May 11 '11 at 15:31
  • @Peter R: looks like this is an example: http://en.wikipedia.org/wiki/C%2B%2B0x#Explicitly-defaulted_and_deleted_special_member_functions – shuttle87 May 11 '11 at 15:32
  • Peter, that is useful when trying to make class non-copyable, for example. Of course moving declaration to private section will do the trick, but this syntax supposed to make code more obvious and provide user with more readable error messages that make sense. –  May 11 '11 at 15:32
  • @peter-r @shuttle87 To prohibit copying for example: http://stackoverflow.com/questions/5702100/whats-the-most-reliable-way-to-prohibit-a-copy-constructor-in-c/5702137#5702137. – AVH May 11 '11 at 15:33
  • @Vlad - The private copy constructor will still let member functions and friends create an accidental copy (or not signal a problem until link time). The new syntax fixes that too. – Bo Persson May 11 '11 at 15:36
  • 1
    @Downvoter: The actual error message was posted as an edit, Initial error message posted was only `C++ error: use of deleted function` – Alok Save May 11 '11 at 15:44
5

I encountered this error when inheriting from an abstract class and not implementing all of the pure virtual methods in my subclass.

Chris Krogh
  • 184
  • 4
  • 16
  • 1
    Similarly, I got the same by deriving `public virtual` from a 2nd-level base class where the 1st-level base class had an explicitly deleted default constructor. Removing `virtual` fixed the issue without having to implement all the methods. – Maitre Bart Jul 03 '20 at 16:21
4

gcc 4.6 supports a new feature of deleted functions, where you can write

hdealt() = delete;

to disable the default constructor.

Here the compiler has obviously seen that a default constructor can not be generated, and =delete'd it for you.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
2

In the current C++0x standard you can explicitly disable default constructors with the delete syntax, e.g.

MyClass() = delete;

Gcc 4.6 is the first version to support this syntax, so maybe that is the problem...

jarmond
  • 1,372
  • 1
  • 11
  • 19
0

Switching from gcc 4.6 to gcc 4.8 resolved this for me.

Michael Bosworth
  • 2,123
  • 18
  • 8
0

If you get this error when initializing an std::atomic variable like so:

std::atomic_bool b = false;

Then it cannot work because this uses copy initialization but copy constructor is explicitly deleted.

Use direct initialization instead:

std::atomic_bool b{false};
Chnossos
  • 9,971
  • 4
  • 28
  • 40