I know that a destructor in C++ does not return a value and its type cannot be explicitly specified.
However, I am wondering whether it can be considered an implicitly void function and whether such a classification is correct according to the C++ standard.
I created a program where type of X destructor is void.
#include <iostream>
#include <cxxabi.h>
using namespace std;
class X
{
};
int main()
{
X *x = new X();
char *fullname;
using destructor_type = decltype(x->~X());
const type_info &destructor_t = typeid(destructor_type);
fullname = abi::__cxa_demangle(destructor_t.name(), NULL, NULL, NULL);
cout << "[DESTRUCTOR] => " << destructor_t.name() << " => " << fullname << '\n';
free(fullname);
}
Can you explain to me how it is with destructor?
Note that the difference between an ordinary function's type and its return type. Given the declaration
double f(int);
the type of f is double(int) or "function of int returning double". The return type of f is double.
To be technically correct (the best kind of correct):
x->~X()) has type void.So,
struct X { ~X(); };
X x;
// Both are errors: Naming a destructor can only be done in
// a declaration or definition, or in a call expression with ().
// If they were valid, the destructor has no type anyway.
using T1 = decltype(X::~X);
using T2 = decltype(x.~X);
using T3 = decltype(x.~X());
static_assert(std::is_same_v<T3, void>); // OK
Note that sometimes decltype gives the type from a name's declaration and sometimes it gives a type based on the type and value category of the expression. This is why decltype(a) and decltype((a)) can be different things. But x.~X() is not directly naming the destructor, so it falls into the category of just getting the expression type, not involving the declaration (explicit or implicit) of ~X.
It's true a destructor is in many ways like a function with return type void: You can use the statement return;, you can't use return with any actual value, and you can't get a value from an expression that calls it.
But there's one little difference showing that a destructor doesn't actually have return type void: A function with return type void can return an expression that has type void. A destructor can't return any expression, even if it does have type void.
void f();
void g(bool b) {
if (b)
return f(); // OK, returning void expression as void
else
return void(); // Strange but valid way of writing "return;"
}
Y::~Y() {
if (this->b)
return f(); // Error, can't put anything after "return"
else
return void(); // Error
}
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