error: use of deleted function
Asked Answered
A

7

172

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?

Aurore answered 11/5, 2011 at 15:25 Comment(4)
and the code that you are compiling?Classroom
I was more just wondering what the error meant? Do I need to post the code for that as well?Aurore
gcc.gnu.org/bugzilla/show_bug.cgi?id=47417 might help, also are you using boost?Classroom
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.Baruch
P
215

The error message indicates that the default constructor has been deleted implicitly because the class contains a non-static, const variable, which would not be initialized by the default constructor (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.

Pumpkinseed answered 11/5, 2011 at 15:35 Comment(7)
@Jeffry Coffin: The actual error message was posted as an edit, Initial error message posted was only C++ error: use of deleted functionApulia
@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.Pumpkinseed
"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?Dagda
@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).Pumpkinseed
@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.Cytochrome
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.Pumpkinseed
@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.Gorgon
A
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.

Apulia answered 11/5, 2011 at 15:28 Comment(8)
Out of curiosity, when would doing something like that be helpful?Pergolesi
@Peter: to prevent implicit conversions.Eo
Actually it says "implicitly deleted because ...", the above example would be explicit.Typhoeus
@Peter R: looks like this is an example: en.wikipedia.org/wiki/…Aurore
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.Amara
@peter-r @Aurore To prohibit copying for example: #5702600.Adverbial
@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.Hamford
@Downvoter: The actual error message was posted as an edit, Initial error message posted was only C++ error: use of deleted functionApulia
F
5

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

Fretful answered 25/7, 2019 at 23:10 Comment(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.Withy
H
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.

Hamford answered 11/5, 2011 at 15:32 Comment(0)
H
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...

Herzen answered 11/5, 2011 at 15:30 Comment(3)
Gcc 4.6 is the first version to support this syntax I guess that would explain why I have never seen it before as I have just started using gcc4.6 recently.Aurore
I've been using this syntax with GCC 4.5 for years. I mean days.Eo
Ah, I must have been thinking of delegated ctors which are in GCC 4.6.Herzen
P
0

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

Parttime answered 13/12, 2013 at 21:14 Comment(0)
T
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};
Tape answered 4/5, 2023 at 16:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.