std::is_destructible

Written by on March 15, 2020 in C++, Programming with 0 Comments

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.

Some structs

Some structs

 The above defines several structs. Here is the main function that applies std::is_destructible<T> on the above structs. 

Applying std::is_destructible

Applying std::is_destructible

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:

Compile Time Check

Compile Time Check

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.

Deleted Destructor

Deleted Destructor

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:

Primitive Types

Primitive Types

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.

Private/Protected Destructor

Private/Protected Destructor

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:

std::is_trivially_destructible

std::is_trivially_destructible

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:

std::is_nothrow_destructible

std::is_nothrow_destructible

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!

Tags: , , ,

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

Subscribe via RSS Feed

Leave a Reply

Your email address will not be published. Required fields are marked *

Top