180

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?

4
  • 5
    and the code that you are compiling? Commented May 11, 2011 at 15:26
  • I was more just wondering what the error meant? Do I need to post the code for that as well? Commented May 11, 2011 at 15:27
  • 1
    gcc.gnu.org/bugzilla/show_bug.cgi?id=47417 might help, also are you using boost? Commented May 11, 2011 at 15:32
  • 42
    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. Commented Jul 24, 2015 at 10:55

8 Answers 8

219

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.

Sign up to request clarification or add additional context in comments.

7 Comments

@Jeffry Coffin: The actual error message was posted as an edit, Initial error message posted was only C++ error: use of deleted function
@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.
"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?
@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).
@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.
|
11

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.

8 Comments

Out of curiosity, when would doing something like that be helpful?
@Peter: to prevent implicit conversions.
Actually it says "implicitly deleted because ...", the above example would be explicit.
@Peter R: looks like this is an example: en.wikipedia.org/wiki/…
@Downvoter: The actual error message was posted as an edit, Initial error message posted was only C++ error: use of deleted function
|
7

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

1 Comment

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

Comments

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

3 Comments

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.
I've been using this syntax with GCC 4.5 for years. I mean days.
Ah, I must have been thinking of delegated ctors which are in GCC 4.6.
2

Deleted function error can be generate with smart pointer in a class.

Example:

class Ctest { public: Ctest(); Ctest(const Ctest&) : m_iX(-1), m_piX(nullptr) { } int m_iX; std::unique_ptr<int>m_piX; }; Ctest cTest; Ctest cTest2(cTest); auto it = m_tcTest.begin()+1; m_tcTest.insert(it,cTest2); 

error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>& std::unique_ptr<_Tp, _Dp>::operator=(const std::unique_ptr<_Tp, _Dp>&)

Template generate the operator deleted state. Because copy operator don't know how copy the member m_piX. It is a safety error.

It is to the developper to decide what to do with m_piX 3 choices: m_piX=nullptr , copy the content, or move the pointer.

Comments

1

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

Comments

0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.