fbpx

Sometimes you need to declare a type to be the same as something else.

You can use decltype just like auto. When you want to declare a local variable and initialize it right away, then auto really is the better choice. But maybe you want to declare a class member variable and your code won’t get around to initializing it with a value until the constructor or some other member method runs. You can’t use auto in this situation because the compiler doesn’t have anything to initialize the value with. As long as you have the other type available, which you should, then that’s all you need for decltype. This will give you the benefits of declaring a data member type based on some other type that could change as you write your application. And you don’t need to worry about initializing it right away. It will still have a specific type.

It also has an added benefit of following the declared type of the expression you pass to decltype exactly. Unlike auto which strips off reference or const qualifiers, the decltype operator will leave those intact.

This is actually one case where you might have to use decltype instead of auto even if you are declaring a local method variable and have an initializer handy. I explained in episode 137 how you can force an auto declaration to be const or to be a reference. But what if you don’t want to force it? What if you want your local variable to be a reference if you’re using a reference type to initialize it and you want it to have its own copy if you’re initializing it with a non-reference? The auto declaration by itself will always give you a new copy of the variable. And an auto reference will always give you a reference. If instead, you want something that can more closely follow the actual declared type of the thing being used to initialize your variable, then use decltype.

There are other uses of decltype too. You’ll find this operator very useful for all those places where you want some type to follow the type of some expression or other type but aren’t interested in using that type right away as an initializer. Listen to the full episode or you can read the full transcript below.

Transcript

In a way, this episode builds on episode 137 about auto. I’ll explain the decltype operator today. First of all, this operator should have been called typeof which would have been similar to sizeof and alignof operators. But the typeof operator was never included in the C++ standard so some compiler vendors added their own typeof extension to the language. Then when the C++ standard committee wanted to add typeof to the language, the members were worried it would cause conflicts with code that was already using the unofficial typeof operator.

The committee needed a different name for expressing the concept of declared types so they came up with the keyword d e c l t y p e. I’m not sure if it has an agreed on pronunciation, so I call it decltype. There are some differences between decltype and auto. And you can even use them together.

But before I start explaining the decltype operator, I want to announce a schedule change for this podcast. I’ve been creating and producing a new episode every weekday for the last eight months but there’s some other projects that need my time. Beginning with this episode, the podcast schedule will change to twice a week on Mondays and Fridays.

The topics are becoming more advanced and can sometimes take four hours or more for me to research and prepare a well thought out episode. That’s not a schedule I can maintain and it really struck me as I was preparing this episode. I’ve been reading all the details and digging into as many dark corners of C++ as I could to present what will be less than ten minutes. This episode alone has taken half a day. Okay, maybe I did get sidetracked a few times. Don’t get me wrong. I love doing this. But I’m working on some really cool things that I think you’ll enjoy too.

The first is that I started writing a book last month. The topic is all about using pointers in C++. When I wasn’t preparing this episode, or outside grilling steaks today, I was writing about pointers and working on the other project.

You should know by now that I can help you learn how to program through live weekend classes. Since I haven’t found a sponsor yet, that’s all you’ve heard each episode. Hopefully, the schedule change will give me time to properly look for a sponsor too. But the other project I’m working on is a compressed form of the weekend classes. I’m putting together multiple week long workshops in different cities where I’ll show you how to build a game. This will be intense and will take some time to organize. Let me know if you’re interested by texting gameweek as a single word to the short number 44222 and I’ll keep you up-to-date.

I’m going to skip the self sponsor today since I’ve already just done that. Let’s get back to decltype.

You can use decltype just like auto but when you want to declare a local variable and initialize it right away, then auto really is the better choice. But maybe you want to declare a class member variable and your code won’t get around to initializing it with a value until the constructor or some other member method runs. You can’t use auto in this situation because the compiler doesn’t have anything to initialize the value with. In fact, there’s probably not not even an instance to hold the data member anyway yet.

As long as you have the other type available, which you should, then that’s all you need for decltype. This will give you the benefits of declaring a data member type based on some other type that could change as you write your application. And you don’t need to worry about initializing it right away. It will still have a specific type.

It also has an added benefit of following the declared type of the expression you pass to decltype exactly. Unlike auto which strips off reference or const qualifiers, the decltype operator will leave those intact.

This is actually one case where you might have to use decltype instead of auto even if you are declaring a local method variable and have an initializer handy. I explained in episode 137 how you can force an auto declaration to be const or to be a reference. But what if you don’t want to force it? What if you want your local variable to be a reference if you’re using a reference type to initialize it and you want it to have its own copy if you’re initializing it with a non reference? The auto declaration by itself will always give you a new copy of the variable. And an auto reference will always give you a reference. If instead, you want something that can more closely follow the actual declared type of the thing being used to initialize your variable, then use decltype.

There are other uses of decltype too. You’ll find this operator very useful for all those places where you want some type to follow the type of some expression or other type but aren’t interested in using that type right away as an initializer.

Maybe you want to declare a method with a return type based on the types of some of the parameters. Or maybe you want the return type to be based on some expression involving some of the parameters.

You could, for example, inside your method decide to return the result of calling another method and passing it one of the parameters. Since the type of the parameter will be used to select the appropriate method to call, remember, the other method could be overloaded, then the actual return type will be based on the return type of this other method. That’s an expression that decltype can help you keep track of.

This is a little vague, I know, so let me try to give you one of my strange analogies. Let’s say you have a new dinner-making machine that you just bought from one of those late night shopping channels. This machine is very advanced though. That’s why you bought it. All you have to do is open the lid and put in ingredients. What type of ingredients? Any type. It’ll figure out what to make based on what you give it. If you put in a raw egg, unbroken, and some bread, you’ll get an egg sandwich. If you put in a broken egg though and some bread, you’ll get french toast.

Now you want to prepare a menu to use this new machine so you write a template method that can take any type of parameters. All you do is pass those argument values to your machine. And you need to return the result from your method. But you don’t know what type the result will be. It all depends on whatever result the machine decides and that depends on the type of ingredients. You can use decltype and tell decltype to evaluate what type will result from giving the ingredients to the machine. Whatever type that results in will be your method return value.