C++11: Can I create a field whose type has a deleted destructor?

c++, c++11

Solution

Some rationale for this behaviour: There's a situation where the destructor of a member object is automatically invoked outside of the containing object's destructor: in case (something in) the containing object's constructor throws. Before the constructor exits, the destructors of already-constructed members and base class subobjects are invoked in reverse order of construction.

Problem

I have a type whose destructor has been explicitly deleted; I'd like to make an instance of that type a member of another class. My expectation is that should be fine provided no attempt is made to delete an instance of the containing class (ie, the containing class's destructor would be invalid). However, both clang (v3.3) and g++ (v 4.6.3) give an error when an attempt is made to instantiate the constructor of the parent class. For example: ``` class DeletedDtor { public: DeletedDtor() {} ~DeletedDtor() = delete; }; class MyClass { public: MyClass() = default; ~MyClass() = delete; private: DeletedDtor a; }; int main() { MyClass *p = new MyClass(); } ``` Under g++, this gives: ``` test.cpp: In function ‘int main()’: test.cpp:19:30: error: use of deleted function ‘MyClass::MyClass()’ test.cpp:11:5: error: ‘MyClass::MyClass()’ is implicitly deleted because the default definition would be ill-formed: test.cpp:11:5: error: use of deleted function ‘DeletedDtor::~DeletedDtor()’ test.cpp:5:5: error: declared here ``` Defining the MyClass constructor myself, rather than letting it take the default implementation, doesn't help either: ``` class DeletedDtor { public: DeletedDtor() {} ~DeletedDtor() = delete; }; class MyClass { public: MyClass(); ~MyClass() = delete; private: DeletedDtor a; }; MyClass::MyClass() : a() {} int main() { MyClass *p = new MyClass(); } ``` Which gives the compilation error: ``` test2.cpp: In constructor ‘MyClass::MyClass()’: test2.cpp:18:24: error: use of deleted function ‘DeletedDtor::~DeletedDtor()’ test2.cpp:5:5: error: declared here ```

Original source