error: use of deleted function - c++

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?

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.

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.

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

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.

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

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

Related

Are copy constructors defined implicitly always, or only when they are used?

Consider the following code:
#include <memory>
#include <vector>
class A
{
private:
std::vector<std::unique_ptr<int>> _vals;
};
int main()
{
A a;
//A a2(a);
return 0;
}
Compiler A compiles this without issue unless I uncomment out the line A a2(a); at which point it complains about the copy constructor for std::unique_ptr being deleted, and therefore I can't copy construct A. Compiler B, however, makes that complaint even if I leave that line commented out. That is, compiler A only generates an implicitly defined copy constructor when I actually try to use it, whereas compiler B does so unconditionally. Which one is correct? Note that if I were to have used std::unique_ptr<int> _vals; instead of std::vector<std::unique_ptr<int>> _vals; both compilers correctly implicitly delete both copy constructor and assignment operator (std::unique_ptr has a explicitly deleted copy constructor, while std::vector does not).
(Note: Getting the code to compile in compiler B is easy enough - just explicitly delete the copy constructor and assignment operator, and it works correctly. That isn't the point of the question; it is to understand the correct behavior.)
From [class.copy.ctor]/12:
A copy/move constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used ([basic.def.odr]), when it is needed for constant evaluation ([expr.const]), or when it is explicitly defaulted after its first declaration.
A's copy constructor is defaulted, so it's implicitly defined only when it is odr-used. A a2(a); is just such an odr-use - so it's that statement that would trigger its definition, that would make the program ill-formed. Until the copy constructor is odr-used, it should not be defined.
Compiler B is wrong to reject the program.
Note: My answer is based on your comment:
[...] it's only on Windows, and only when I explicitly list class A as a DLL export (via, e.g., class __declspec(dllexport) A) that this happens. [...]
On MSDN we can learn that declaring a class dllexport makes all members exported and required a definition for all of them. I suspect the compiler generates the definitions for all non-deleted functions in order to comply with this rule.
As you can read here, std::is_copy_constructible<std::vector<std::unique_ptr<int>>>::value is actually true and I would expect the supposed mechanism (that defines the copy constructor in your case for export purposes) checks the value of this trait (or uses a similar mechanism) instead of actually checking whether it would compile. That would explain why the bahviour is correct when you use unique_ptr<T> instead of vector<unique_ptr<T>>.
The issue is thus, that std::vector actually defines the copy constructor even when it wouldn't compile.
Imho, a is_copy_constructible check is sufficient because at the point where your dllexport happens you cannot know whether the implicit function will be odr-used at the place where you use dllimport (possibly even another project). Thus, I wouldn't think of it as a bug in compiler B.
While I can't confirm this behavior (I do not have access to Windows compiler, and OP claims the bug happens with icc on Windows platform), taking the question at it's face value, the answer is - compiler B has a gross bug.
In particular, implicitly-declared copy constructor is defined as deleted, when ...
T has non-static data members that cannot be copied (have deleted,
inaccessible, or ambiguous copy constructors);
https://en.cppreference.com/w/cpp/language/copy_constructor
Thus, conforming compiler must semantically generate deleted copy-constructor, and successfully compile the program since such constructor never called.

delete modifier vs declaring function as private

I read this question, but it still doesn't make a lot of sense to me. It still sounds more like a sugarcoating feature.
What's the difference between:
class A
{
// public/private ?
A (const A&) = delete;
};
and
class A
{
private:
A (const A&); // MISSING implementation
};
Same for operator= or other functions.
One difference is that =delete allows for compile-time errors while in some cases the declaration without a definition is only caught at link-time (at which the error message is typically not pointing you to the source of the problem). One such case is when you add a member function that tries to copy an instance of A. Even when it's not a member function of A, the error message about the copy-ctor being private is not as clear as using =delete.
To avoid confusion, I'd recommend you make the deleted function public as otherwise you will get additional and misleading error messages.
The difference is that the purpose of the =delete code is explicit in it's purpose. Declaring functions as private / inaccessible was a trick. Although most people knew it, the error it generated was obscure (a linking/access level error instead of a semantical problem in the code - i.e. "you are using a deleted function").
One difference is that the old-fashioned form gives undefined behaviour if the class (or a friend) tries to destroy itself. Within class members and friends, the destructor is accessible, so there is no compile-time error if it's used. Instead, you get a violation of the One Definition Rule. In practice, this will cause a link error, but formally the behaviour is undefined.
Deleting the constructor (or other function) causes a compile error if the function is needed in any circumstances; and states the intent more explicitly, allowing the compiler to give better diagnostic messages. This is especially useful when functions are implicitly deleted due to something else being deleted.
Another thing which hasn't been mentioned yet: when inheriting / overriding, you can't =delete a function which already has a body but you can change a public function into a private one, making it basically inaccessible from outside.

Question on predefined meanings for operators

In "The C++ programming language", at page 265, the author makes the following statement:
Because of historical accident, the operators = (assignment), & (address-of), and , (sequencing;
§6.2.2) have predefined meanings when applied to class objects. These predefined meanings can
be made inaccessible to general users by making them private:
Then the following example is given:
class X {
private:
void operator=(const X&);
void operator&();
void operator,(const X&);
// ...
};
void f(X a, X b)
{
a = b; // error: operator= private
&a; // error: operator& private
a,b; // error: operator, private
}
I can't quite understand what do these "error" comments refer to? Does that mean I should not define a function like f, or that all of the =, &, and , operators should be used according to the default way, and it is not necessary to redefine them?
This example simply shows a way to prevent yourself or other developers of the code from using operators, which can be used without having been defined in the class, because they're automatically generated (and have default meanings for the operations they represent).
The author of the example meant, that if you try to assign b to a (in line a = b) it will cause an error, because the assignment operator is private in the class definition.
Similar error occurs in case of address-of in the second line, and the comma operator in the third.
Making default operators/constructors private if you know they're not supposed to be used (or haven't been implemented yet) is good, because one may accidentally use a very frequent operator like assignment or copy-constructor, being unaware that it's default behavior conflicts with the class lifecycle. If such operator or constructor is made private at the very beginning of class design, the compiler will generate a compile-time error instead of performing a potentially dangerous operation without notice if the programmer accidentally uses the method.
Think default assignment operator and member pointer: it will copy the pointer whereas you might want the object to be the owner of data. Then, after someone assigns one object to another without knowing that assignment is not implemented, you will end up with a double free error. Instead of that, if the operator is private, you'll get a nice error and the code will not even compile, and you'll know what's going on.
The author intends to point out here that the operators =, & and , are usually implicitly available for a class.
So if you don't want your objects to be operated on through them then you declare them as private thus disallowing their use.
Since they are declared as private you cannot access them anymore outside the class and the compiler gives you a compilation error. The function is an example showing that.
Providing your own implementation of any operator is basically the same as implementing a class method. Operators and methods are the same in terms of accessibility. What you do is disallowing access to operators from the caller's code.
It's absolutely the same as if you defined a private method and then tried to call it from some code that is not part of your class. Just make the operators public and errors will go away.
It basically prevents any one from making an 'X' object and using the "=", "&", and "," operators on that class. Because the author of the class may implement those objects with a meaning that is quite different to what the consumer of the class might think they do ... so its best to prevent them being used at all in the case of ambiguity.
The function f is an example of a user trying to use the private operators. It shows you what code it is that you're preventing by making them private. The comment // error means that a program that contained that line would fail to compile for the stated reason.
Before discussing the error, a key here is to understand that these operations will be implicitly made available for your class. This is the essence of Scott Meyers' advice "Know what functions C++ silently writes and calls."
C++ will automatically implement the assignment operator for your class, but it may not be done correctly (for example, if your class contains a pointer member variable). By defining the assignment operator explicitly, you are telling the compiler to use your implementation instead of generating one for you. And by making it private, you are essentially disallowing assignment of one class instance to another. Anywhere you try to do this in your code, the compiler will complain, which is a good thing if you really don't want assignment to be done.
In function f the author is showing you that these statements will not compile because of how the operators are defined in the class. It is perfectly acceptable to redefine operators for your class, and sometimes it is definitely required (for example, to implement a deep copy of a pointer member variable in your class). The point of the example is to show that a) you can provide your own implementation of these operators for your class, and b) because of this you have control over whether the operators are supported and implemented correctly for your class.

Opt-out of copy constructor

This might be a silly question, but...
I've been writing a number of classes that utilize non-copyable members. These classes are never initialized via the copy constructor in my source. When I try to compile without supplying my own copy-constructor, g++ throws out many errors about how it can't build a default copy constructor, due to the non-copyable member objects.
Is there a way to tell the compiler to just not give me a copy constructor?
EDIT: Yeah... feels silly... I had a case where I was invoking the copy-constructor by accident in a boost::bind call. Lesson learned.
The usual way to make things noncopyable is to declare but not define a copy constructor, and make it private so nothing can call it.
The next revision of the language will provide an explicit way to suppress these generated functions.
If you don't actually cause the copy-constructor to be called then it is not an error if the compiler would be unable to generate one. It sounds like you are (possibly indirectly) causing the copy-constructor to be used.
You can suppress the compiler generated one by declaring your own copy-constructor (you don't need to define it if you're not using it). You can place it in the private section of your class.
If this changes the error to say that the copy-constructor is inaccessible or you get link errors then you really are causing the copy-construtor to be used and you need to analyze why this is.
Not in the current version of C++. In C++ 0x, there will be an =delete; syntax to tell it that you don't want one of the special member functions the compiler will generate by default if you don't defined one yourself.
Until the new C++ 0x standard is fully supported, the best you can do is to delclare a version of the special member function, but not implement them. Normally they are made private (to help make it clear that they shouldn't be used).
Class foo
{
// ... rest of definition
private:
foo (const foo& rhs); // Do Not Implement
const foo& operator= (const foo& rhs); // Do Not Implement
};
No :)
If you want your class to be non-copyable use something like boost::noncopyable
class MyClass : private boost::noncopyable
{
}
or use a parametrizied macro in your class definition that declares a private copy constructor.

Macros to disallow class copy and assignment. Google -vs- Qt

To disallow copying or assigning a class it's common practice to make the copy constructor
and assignment operator private. Both Google and Qt have macros to make this easy and visible.
These macros are:
Google:
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
Qt:
#define Q_DISABLE_COPY(Class) \
Class(const Class &); \
Class &operator=(const Class &);
Questions:
Why are the signatures of the two assignment operators different? It seems like the Qt version is correct.
What is the practical difference between the two?
It doesn't matter. The return type is not part of a function's signature, as it does not participate in overload resolution. So when you attempt to perform an assignment, both declarations will match, regardless of whether you use the return type.
And since the entire point in these macros is that the functions will never get called, it doesn't matter that one returns void.
I'd just like to mention that there is an alternative strategy for implementing an abstraction for disallowing copy and assignment of a class. The idea is to use inheritance instead of the preprocessor. I personally prefer this approach as I follow the rule of thumb that it is best to avoid using the preprocessor when at all possible.
boost::noncopyable is an example implementation. It is used as follows:
class A : noncopyable
{
...
};
See Boost.Utility, specifically boost::noncopyable. It's not a macro but a base class with private copy and assignment. It prevents the compiler from generating implicit copy and assignment in derived classes.
edit: Sorry, this was not an answer to the original question. By the way, boost::noncopyable uses a const reference as return type for the assignment operator. I was under the impression that the type of the return value doesn't matter since it's not supposed to be used. Still, making the operator private doesn't prevent usage inside the class or friends in which case a non-usual return type (like void, a const reference, etc) might lead to compilation errors and catch additional bugs.
There's no practical difference. The assignment operator signatures differ just as a matter of style. It's usual to have an assignment operator returning a reference to allow chaining:
a = b = c;
but a version returning void is also legal and will work just fine for cases when the only purpose is to just declare the operator private and therefore prohibited to use.
From the standard, 12.8, clause 9: "A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X&, or const volatile X&." It says nothing about the return type, so any return type is permissible.
Clause 10 says "If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly."
Therefore, declaring any X::operator=(const X&) (or any other of the specified assignment types) is sufficient. Neither the body nor the return type is significant if the operator will never be used.
Therefore, it's a stylistic difference, with one macro doing what we'd likely expect and one saving a few characters and doing the job in a way that's likely to surprise some people. I think the Qt macro is better stylistically. Since we're talking macro, we're not talking about the programmer having to type anything extra, and failing to surprise people is a good thing in a language construct.
Others have already answered why it's legal to have different return values for operator=; IMHO jalf said it best.
However, you might wonder why Google uses a different return type, and I suspect it's this:
You don't have to repeat the type name when disabling the assignment operator like this. Usually the type name is the longest part of the declaration.
Of course, this reason is void given that a macro is used but still - old habits die hard. :-)
Both serve the same purpose
Once you write this one:
Class &operator=(const Class &);
you will get the benefits of chain assignments. But in this case you want the assignment operator to be private. so it doesn't matter.
Qt version is backward compatible, while google's is not.
If you develop your library and deprecate the use of assignment before you completely remove it, in Qt it will most likely retain the signature it originally had. In this case older application will continue to run with new version of library (however, they won't compile with the newer version).
Google's macro doesn't have such a property.
As several other answers have mentioned, the return type of the function doesn't participate in the function signature, so both declarations are equivalent as far as making the assignment operator unusable by clients of the class.
Personally I prefer the idiom of having a class privately inherit from an empty non-copyable base class (like boost::noncopyable, but I have my own so I can use it in projects that don't have boost available). The empty base class optimization takes care of making sure there's zero overhead, and it's simple, readable, and doesn't rely on the dreaded preprocessor macro functionality.
It also has the advantage that copy and assignment can't even be used within class implementation code - it'll fail at compile time while these macros will fail at link time (likely with a less informative error message).
Incidentally, if you have access to the Boost libraries (You don't? Why the heck not??), The Utility library has had the noncopyable class for a long time:
class YourNonCopyableClass : boost::noncopyable {
Clearer IMHO.
In practice I would say that both should not be used anymore if you have a C++11 compiler.
You should instead use the delete feature , see here
Meaning of = delete after function declaration
and here
http://www.stroustrup.com/C++11FAQ.html#default
Why : essentially because compiler message is much more clearer. When the compiler need one of the copy or copy assignment operator, it immediately points out to the line where the =delete was coded.
Better and complete explanations can also be found in Item 11: Prefer deleted functions to private undefined ones from Effective Modern C++ book by Scott Meyers