Reputation: 3082
class Part
{
public:
~Part() = delete;
};
class CL
{
public:
CL(){} //error: deleted destructor call
~CL();
Part part;
};
int main()
{
}
This code gives an error associated with a Part
's deleted destructor call. What is context in default constructor for members destructor calling?
P.S: As I know, destructor for a Part
member must be called in ~CL()
, but it is specially not defined for demonstrating, that default constructor forces it anywhere
Upvotes: 1
Views: 174
Reputation: 13040
First, Part
is a potentially constructed subobject of CL
according to [special]p5.
For a class, its non-static data members, its non-virtual direct base classes, and, if the class is not abstract, its virtual base classes are called its potentially constructed subobjects.
So the destructor for Part
is potentially invoked according to [class.base.init]p12, regardless of the existence of nonexcept
or not.
In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked.
Therefore the program is ill-formed according to [class.dtor]p12.
A program is ill-formed if a destructor that is potentially invoked is deleted or not accessible from the context of the invocation.
Note even though the deleted destructor is not actually invoked, the program is ill-formed as long as the destructor is potentially invoked.
Upvotes: 1
Reputation: 29022
Every constructor needs to have access to it's members' destructors. When a constructor throws an exception, it must be able to destroy every member that was initialized before the exception was thrown. You can verify that this is true for every constructor. If you try adding arbitrary arguments to the constructor, the error still occurs, even with copy and move constructors.
As it was mentioned in the comments, CL() = default;
doesn't produce the error. This is because CL() = default;
simply causes the compiler to produce the implicit default constructor it would normally generate. In this case, it appears the CL has a deleted implicitly-declared default constructor, meaning the automatically generated implicit default constructor would be deleted. If you try the following, you see that the default constructor is not actually available :
#include <type_traits>
class Part
{
public:
~Part() = delete;
};
class CL
{
public:
CL() = default;
~CL();
Part part;
};
// This assert passes
static_assert(std::is_default_constructible<CL>::value == false, "");
However, I can't explain precisely why CL has a deleted implicitly-declared default constructor, nor can I explain why CL() noexcept {};
doesn't work.
Upvotes: 2