Questions tagged [variant]

A variant data type is a tagged union that holds other data types. It is a standard data type in [ocaml], and typically used for interop calls between languages ([c++] and [vb6]) in classic Microsoft Windows [com] programming. It also exists in other languages using other names, such as [discriminated-unions] or the more general concept of [algebraic-data-types]

In , the variant type is a basic building block of the language. Custom variants are defined with a set of constructors that restrict which types it can hold, and are used to inspect it in and to warn if a pattern match does not cover all constructors.

Questions that should have this tag would include ones involving how to pass data between Windows processes or within the same process using and classic function calls. Often the calls occur between languages (e.g. to ), but they are also used in single language programs (e.g. ) to achieve a plug-in, modular architecture with DLL files.

A variant is technically a structure holding a union of data types along with a VARTYPE that indicates which member of the structure is valid. It can hold any other data type, including primitive types (BYTE, LONG), pointers to primitive types (LONG*, FLOAT*), IDispatch pointers, and even pointers to other variants.

There are a couple of helper classes Microsoft has created to help with the details of dealing with raw variants:

These classes relieve much of the grunt work of interop programming with variants such as doing deep destroys on contained SAFEARRAYs.

Definitions

  • Tagged union: A data structure that can be used to hold a number of different data types, only one of which is valid at a time. There is a field (VARTYPE) which indicates the valid data member (https://en.wikipedia.org/wiki/Tagged_union)

Examples

OCaml

(* Definition of the built-in option type *)
type 'a option =
| Some of 'a
| None

(* Construction *)
let var = Some "hello"

(* Inspection through pattern matching *)
let greeting =
  match var with
  | Some str -> str
  | None -> "howdy"

Visual Basic

Dim var as Variant

var = "hello"   'Variant holds a string

var = 7         'Variant holds an Integer

C++

_variant_t var;

var = "hello";  //Variant holds a string

var = 7;        //Variant holds an int

Resources

Related tags

1152 questions
25
votes
2 answers

Is std::variant allowed to allocate memory for its members?

I was wondering if an implementation of std::variant must necessarily be "flat" or whether it is allowed to dynamically allocate memory for its members, such that a sequence of variants would degenerate to a sequence of pointers, thereby destroying…
bitmask
  • 32,434
  • 14
  • 99
  • 159
25
votes
2 answers

Convert std::variant to another std::variant with super-set of types

I have a std::variant that I'd like to convert to another std::variant that has a super-set of its types. Is there a way of doing it than that allows me to simply assign one to the other? template ToVariant…
Bomaz
  • 1,871
  • 1
  • 17
  • 22
24
votes
5 answers

Is there an existing name for this type and function?

There are 2 hard problems in computer science: cache invalidation, naming things and off-by-one errors. This is about the 2nd problem: naming things. I'm looking if this technique or type has been used somewhere else already and has a name. …
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
24
votes
5 answers

How to store variant data in C++

I'm in the process of creating a class that stores metadata about a particular data source. The metadata is structured in a tree, very similar to how XML is structured. The metadata values can be integer, decimal, or string values. I'm curious if…
Perculator
  • 1,293
  • 1
  • 10
  • 12
22
votes
6 answers

How to check whether a variant array is unallocated?

Dim Result() As Variant In my watch window, this appears as Expression | Value | Type Result | | Variant/Variant() How do I check the following: if Result is nothing then or if Result is Not Set then This is basically what I…
jason m
  • 6,519
  • 20
  • 69
  • 122
22
votes
2 answers

Why does std::visit take a variable number of variants?

Trying to get more familiar with C++17, I've just noticed std::visit: template constexpr /*something*/ visit(Visitor&& vis, Variants&&... vars); Why does std::visit not take a single variant, but rather any number…
einpoklum
  • 118,144
  • 57
  • 340
  • 684
21
votes
2 answers

Return type std::optional>

I have a situation where a function must return a value taken from a table. A cell in this table (let's assume the table just works...) may contain a value, or it might not. This value can also be one of several types: int, double, string, date…
dani
  • 3,677
  • 4
  • 26
  • 60
20
votes
3 answers

What are the differences between std::variant and boost::variant?

In an answer to this SO question: What is the equivalent of boost::variant in the C++ standard library? it is mentioned that boost::variant and std::variant differ somewhat. What are the differences, as far as someone using these classes is…
einpoklum
  • 118,144
  • 57
  • 340
  • 684
20
votes
2 answers

How to use variant arrays in Delphi

I have two Delphi7 programs: a COM automation server (EXE) and the other program which is using the automation server. I need to pass an array of bytes from one program to the other. After some searching I've found that using variant arrays is the…
Steve
  • 2,510
  • 4
  • 34
  • 53
19
votes
5 answers

check boost::variant for null

I have a boost::variant in my program and I want to check if the variant itself is initialized and also if there is a value contained in one of it's types. I've tried empty() on the variant, but that doesn't seem to work. Neither does checking…
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
19
votes
2 answers

std::variant<>::get() does not compile with Apple LLVM 10.0

I'm playing with the C++17 std::variant type and tried to compile the cppreference example code for get(): #include #include int main() { std::variant v{12}, w; int i = std::get(v); w =…
Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
17
votes
2 answers

Why does my variant convert a std::string to a bool?

My std::variant can be empty (std::monostate), contain an int, a std::string or a bool. When I want to feed it with a string, given as var = "this is my string", it gets converted to a bool and not to a string. If I declare the type explicitly, it…
dani
  • 3,677
  • 4
  • 26
  • 60
16
votes
2 answers

Is there any hope to call a common base class method on a std::variant efficiently?

The way std::variant dispatches to different visitor methods when std::visit is called is pretty reasonable when the variant alternatives are completely different types. Essentially a visitor-specific vtable is built at compile-time and after some…
BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
15
votes
2 answers

Excel VBA: Variants in Array Variables

A question on variants. Im aware that variants in Excel vba are both the default data type and also inefficient (from the viewpoint of overuse in large apps). However, I regularly use them for storing data in arrays that have multiple data types. …
Surferosa
  • 218
  • 1
  • 4
  • 9
15
votes
2 answers

Is GCC9 avoiding valueless state of std::variant allowed?

I recently followed a Reddit discussion which lead to a nice comparison of std::visit optimization across compilers. I noticed the following: https://godbolt.org/z/D2Q5ED Both GCC9 and Clang9 (I guess they share the same stdlib) do not generate code…
Flamefire
  • 5,313
  • 3
  • 35
  • 70
1
2
3
76 77