Consider the following code:
#include <iostream>
class Test
{
public:
constexpr Test(const int x) : _x(x) {}
constexpr int get() const {return _x;}
~Test() {} // HERE
protected:
const int _x;
};
int main()
{
static constexpr Test test(5);
return 0;
}
If I remove the line HERE
the code compiles well, but if I define an empty destructor, it results to a compilation error saying that Test
is non-literal.
Why and what is the difference between an empty destructor and no destructor at all ?
EDIT: Another related question : if empty and literal destructors are different how to define a protected literal destructor ?
Quotes from n3376
7.1.5/9
A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression
3.9/10
A type is a literal type if:
it has a trivial destructor...
12.4/5
A destructor is trivial if it is not user-provided and if:
— the destructor is not virtual,
— all of the direct base classes of its class have trivial destructors, and
— for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
Otherwise, the destructor is non-trivial.
clang diagnostic is really more informative:
error: constexpr variable cannot have non-literal type 'const C'
'C' is not literal because it has a user-provided destructor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With