In the last article, I explained the deleted destructor in some detail. Today, I would like to talk about a related construct, a type trait called std::is_destructible.
Type traits, defined in the header <type_traits>, are a big help when it comes to implementing template metaprogramming. See this article for a nice introduction to type traits in C++.
The std::is_destructible trait checks whether objects of the given type T can be destroyed. What does this mean? Let us go through some examples.
The above defines several structs. Here is the main function that applies std::is_destructible<T> on the above structs.
All these types have either the default or an explicit destructor, and hence objects of these types can be destroyed in the normal way. So, as expected, the program prints true for all of them.
Note that we do not have to create objects of these types in order to check if they are destructible.
Some of you may be wondering if std::is_destructible depends on compile time or run time check. The answer is that this is purely a compile time check! Isn’t that interesting? Look at the modified main below:
The above code compiles without any error, but does not print anything at run time. You can read about static_assert here.
OK. Let us now consider some examples where the destructor has been deleted.
In all the above cases, objects of these types cannot be destroyed. If you recall our discussion on deleted destructors in the earlier article, you will agree that the above behaviour is as expected.
Can we apply std::is_destructible to primitive types? Of course. See below:
Notice that the output is true in all except the last two cases.
Although it is not directly relevant, let us also consider the case of a destructor being private or protected. The following code fragment shows what happens in these cases.
Although X destructor is accessible from within X::foo(), is_destructible<X> returns false!
std::is_trivially_destructible
This is a variant of std::is_destructible. See this page for the official specification. Here are some examples:
Hope you understand why line 27 generates false. The class Z has a deleted destructor and so it cannot be destroyed. So, if std::is_destructible is false, then so is std::is_trivially_destructible.
std::is_nothrow_destructible
This is yet another variant. It checks if the underlying T is destructible, and in addition, if the destructor is present, whether it is declared noexcept(true).
Here are some examples:
By default, a destructor is noexcept.
Well, that is it for today. Hope I managed to convey the essence of the traits std::is_destructible, std::is_trivially_destructible and std::is_nothrow_destructible.
You can download the source files from here. I used Visual Studio 2019 ver 16.4.5 to test the examples.
Have a nice weekend!
Recent Comments