The variant type can take on one of many different types and can even change it’s type. It’s still a variant so it’s more accurate to say that it can hold another type.
Think of a collection that can hold many values all of the same type. Now switch that around and you have a variant that can hold a single value of many possible types.
It’s very common in Windows because of the Visual Basic language. I’m referring to the older Visual Basic before it became part of .Net. In those early versions, you could declare a variable and assign it strings, numbers, and likely other objects. I don’t know a lot about it and it’s not used anymore. However, the concept of its unspecified and fluid data type made its way into scripting and into the operating system through COM. Many of the components that the operating system exposes through COM objects wanted to be compatible with Visual Basic scripting so they started using a data type that Visual Basic could easily understand.
For now, think of COM as a way that your program can create well known objects sort of like a library of functionality. These objects might get created inside your application process or in a different process or sometimes even on a different machine. They were and still are used to isolate your code from differences in how various compilers organize objects in memory, how data gets sent back and forth between components, and how to find and create such objects. For an operating system like Windows, understanding COM is an important topic and will allow you to interact with services unavailable through any other means.
And that means if you plan to do any real interaction with Windows, you’ll need to sometimes use variants. Even though the original need for variants doesn’t exist, they continue to be used.
To understand how variants work, you need to understand what a union is. This is a capability that comes from the C language to save memory. You can almost think of a union like a time-share vacation condo. Only one family can use the condo at any given time. And it would be a waste to reserve a whole condo for a single family when it would just sit empty most of the time.
You could if you wanted to create a class that contained one of every basic data type. It would have a single bool data member, a single char data member, a single int, etc. Since you’ll only be using one of these at any time, you’ll also need a data member to remember which one is active.
All the data members are taking up space in memory even though only one of them is being used. This would work even though it wastes a lot of memory. A union allows you to stack all the data members on top of one another. You have to be careful with this because if you write an int through an int variable that’s part of a union and then try to read a float through a float variable, you won’t get anything close to what you expect. That’s because the two variables each have their own way of representing values. As long as you work with a single variable at a time, you’ll be okay.
This is really the same way that a variant works. It starts out with a numeric value that’s used to identify the type of data currently stored in the union. And then it holds a value that matches that type and accesses that value through a union of variables all using the same memory.