[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #7 from Jonathan Wakely redi at gcc dot gnu.org 2013-04-11 12:42:52 UTC --- You keep quoting Stroustrup but your code is still broken. Your clone() function copies the object. The object is not copyable. What is so difficult to understand? Add a copy constructor to vector_stack or change the clone function. This is not a GCC bug!
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #8 from Amali Praveena amalisperid at yahoo dot com 2013-04-12 03:39:35 UTC --- Hi reddit, Yes, it's not a GCC bug. I had a problem with copy constructors in version 4.7.0 but got Internal Compilation Error. I'm now working with GCC 4.8.0 in which this is fixed. I think I got confused with this. I thought of adding these delete functions to the abstract class and test it. Since vector_stack doesn't have any pointer members/ members of its own, I can rely on compiler to generate a default copy constructor for this more derived class of Stack. Option 1: As you say, because I have made copy/move operations in the abstract type(Stack) =delete, I think I should define a default copy constructor/assignment and move constructor/assignment in all more derived classes of Stack. Option 2: Change the clone function. However, Clone pattern is often implemented using copy constructor. Until now, I haven't seen it done in some other ways. Thanks, Amali. From: redi at gcc dot gnu.org gcc-bugzi...@gcc.gnu.org To: amalispe...@yahoo.com Sent: Thursday, 11 April 2013 10:42 PM Subject: [Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #7 from Jonathan Wakely redi at gcc dot gnu.org 2013-04-11 12:42:52 UTC --- You keep quoting Stroustrup but your code is still broken. Your clone() function copies the object. The object is not copyable. What is so difficult to understand? Add a copy constructor to vector_stack or change the clone function. This is not a GCC bug!
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 Daniel Krügler daniel.kruegler at googlemail dot com changed: What|Removed |Added CC||daniel.kruegler at ||googlemail dot com --- Comment #1 from Daniel Krügler daniel.kruegler at googlemail dot com 2013-04-09 09:10:52 UTC --- There are several problems in your example: 1) You have not declared a default constructor in template Stack, but you have provided user-declared constructors (The deleted ones). This has the effect that the Stack template has a no implicitly declared default constructor, which again has the effect that the initializer-list constructor generated by the compiler in vector_stack is deleted, because it would implicitly call the missing default constructor of Stack. Solution: Add a (defaulted) default constructor to the Stack template. 2) The clone function in vector_stack would call the copy constructor of that type. But this one is deleted, because the Stack template has an explicitly deleted copy constructor. This is a design error.
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #2 from Daniel Krügler daniel.kruegler at googlemail dot com 2013-04-09 09:36:29 UTC --- (In reply to comment #1) In addition I would like to remark that the precise declaration state of the inherited initializer-list constructor in vector_stack is unclear, because of http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1573 But the existing wording implies that any usage of this constructor would be ill-formed because of the unavailable default constructor of its base class.
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 Jonathan Wakely redi at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution||INVALID --- Comment #3 from Jonathan Wakely redi at gcc dot gnu.org 2013-04-09 12:26:18 UTC --- As Daniel says, you're missing a default constructor. And if you define the type as non-copyable then obviously you can't copy it. This is not a GCC bug.
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #4 from Amali Praveena amalisperid at yahoo dot com 2013-04-09 19:02:32 UTC --- Hi Jonathan, The Stack in the example is an abstract type, so I'm explicitly saying that this abstract type cannot be copied or moved; but the derived class vector_stack, which provides implementation for this abstract type is copyable through clone function. Since the compiler won't know to which more derived class the Stack points to at run time and so it cannot copy it, I've provided the clone function (clone pattern). This is what bjarne stroustrup says in his draft version of PL Fourth Edition, as I quoted before. Here is that section from the book. 3.3.4 Prev enting Copy and Move [tour2.copy.hier] Using the default copy or move for a class in a hierarchy is typically a disaster: Given only a pointer to a base, we simply don’t know what members the derived class has (§3.3.3), so we can’t know how to copy them. So, the best thing to do is usually to delete the default copy and move operations; that is, to eliminate to default definitions of those two operations: class Shape { public: Sha pe(const Sha pe) =delete; // no copy operations Sha pe opera tor=(const Sha pe) =delete; Sha pe(Sha pe) =delete; // no move operations Sha pe opera tor=(Shape) =delete; ˜Sha pe(); // ... }; Now an attempt to copy a Sha pe will be caught by the compiler. If you need to copy an object in a class hierarchy, write some kind of clone function (§22.2.4). In case you forgot to delete a copy or move operation, no harm is done. A move operation is not implicitly generated for a class where the user has explicitly declared a destructor. Furthermore, the generation of copy operations are deprecated in this case (§42.2.3). This can be a good reason to explicitly define a destructor even where the compiler would have implicitly provided one (§17.2.3). The C++ Programming Language, 4th edition ©2012 by Pearson Education, Inc. Reproduced in draft form with the permission of the publisher. D R A F T Thanks, Amali. From: redi at gcc dot gnu.org gcc-bugzi...@gcc.gnu.org To: amalispe...@yahoo.com Sent: Tuesday, 9 April 2013 10:26 PM Subject: [Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 Jonathan Wakely redi at gcc dot gnu.org changed: What |Removed |Added Status|UNCONFIRMED |RESOLVED Resolution| |INVALID --- Comment #3 from Jonathan Wakely redi at gcc dot gnu.org 2013-04-09 12:26:18 UTC --- As Daniel says, you're missing a default constructor. And if you define the type as non-copyable then obviously you can't copy it. This is not a GCC bug.
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #5 from Daniel Krügler daniel.kruegler at googlemail dot com 2013-04-09 19:13:55 UTC --- This issue is not the right place for discussing programming idioms, but as a last comment to the code: Your reference to PL alone does not solve your programing error: You need to define a copy constructor in vector_stack, because the compiler-defined one is also deleted (because of the deleted one in the base class), or define the clone function without a copy constructor.
[Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 --- Comment #6 from Amali Praveena amalisperid at yahoo dot com 2013-04-09 19:23:38 UTC --- Hi Daniel, The Stack template is an abstract type, so I don't have to add default constructor to it, do I? Since the abstract type can't be copied/moved, i'm explicitly specifying those functions as delete; but the derived classes (vector_stack) are copyable through clone function(clone pattern). I tried to do the following (adding default constructor), which still gave me an error(both options): templateclass T class Stack{ public: // pure virtual member functions virtual Stack* clone() const=0; // polymorphic virtual ~Stack() {} // explicitly define a destructor // no copy operations Bug No:- 56889 Stack() // option 1 { } Stack()=default; // option 2 Stack(const Stack)=delete; Stack operator=(const Stack)=delete; //no move operations Stack(Stack)=delete; Stack operator=(Stack)=delete; virtual bool empty() const=0; // const member function virtual std::size_t size() const=0; // const member function virtual T top()=0; virtual const T top() const=0; // const member function virtual void push(const T x)=0; virtual void pop()=0; }; Here is a section from Bjarne stroustrup's PL fourth edition draft version : Preventing Copy and Move [tour2.copy.hier] Using the default copy or move for a class in a hierarchy is typically a disaster: Given only a pointer to a base, we simply don’t know what members the derived class has (§3.3.3), so we can’t know how to copy them. So, the best thing to do is usually to delete the default copy and move operations; that is, to eliminate to default definitions of those two operations: class Shape { public: Sha pe(const Sha pe) =delete; // no copy operations Sha pe opera tor=(const Sha pe) =delete; Sha pe(Sha pe) =delete; // no move operations Sha pe opera tor=(Shape) =delete; ˜Sha pe(); // ... }; Now an attempt to copy a Sha pe will be caught by the compiler. If you need to copy an object in a class hierarchy, write some kind of clone function (§22.2.4). In case you forgot to delete a copy or move operation, no harm is done. A move operation is not implicitly generated for a class where the user has explicitly declared a destructor. Furthermore, the generation of copy operations are deprecated in this case (§42.2.3). This can be a good reason to explicitly define a destructor even where the compiler would have implicitly provided one (§17.2.3). A base class in a class hierarchy is just one example of an object we wouldn’t want to copy. The C++ Programming Language, 4th edition ©2012 by Pearson Education, Inc. Reproduced in draft form with the permission of the publisher. D R A F T thanks, Amali. From: daniel.kruegler at googlemail dot com gcc-bugzi...@gcc.gnu.org To: amalispe...@yahoo.com Sent: Tuesday, 9 April 2013 7:10 PM Subject: [Bug c++/56889] =delete(ing) default copy and move operations for a polymorphic type gives compilation error messages http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56889 Daniel Krügler daniel.kruegler at googlemail dot com changed: What |Removed |Added CC| |daniel.kruegler at | |googlemail dot com --- Comment #1 from Daniel Krügler daniel.kruegler at googlemail dot com 2013-04-09 09:10:52 UTC --- There are several problems in your example: 1) You have not declared a default constructor in template Stack, but you have provided user-declared constructors (The deleted ones). This has the effect that the Stack template has a no implicitly declared default constructor, which again has the effect that the initializer-list constructor generated by the compiler in vector_stack is deleted, because it would implicitly call the missing default constructor of Stack. Solution: Add a (defaulted) default constructor to the Stack template. 2) The clone function in vector_stack would call the copy constructor of that type. But this one is deleted, because the Stack template has an explicitly deleted copy constructor. This is a design error.