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
15
votes
1 answer

Is there a way to reset a std::variant from a known alternative?

I'm in the process of updating a codebase that is currently using a custom equivalent of std::variant to C++17 . In certain parts of the code, the variant is being reset from a known alternative, so the class provides a method that asserts that…
user4442671
15
votes
1 answer

Cannot initialize std::variant with various lambda expressions

I'm playing with std::variant, lambdas and std::future, and got super weird results when I tried to compose them together. Here are examples: using variant_t = std::variant< std::function(int)>, …
Dmitry Katkevich
  • 883
  • 7
  • 26
15
votes
5 answers

How can I assign a Variant to a Variant in VBA?

(Warning: Although it might look like one at first glance, this is not a beginner-level question. If you are familiar with the phrase "Let coercion" or you have ever looked into the VBA spec, please keep on reading.) Let's say I have an expression…
Heinzi
  • 167,459
  • 57
  • 363
  • 519
14
votes
1 answer

Why is std::variant unable to hold array object types while union can?

Here is simple example, We can define a low level union like this : static union { uint64_t a; uint8_t b[8]; }; but we cannot declare std::variant like this(please do not care about syntax,correct me if I am wrong!, just grab the…
Buddhika Chaturanga
  • 957
  • 2
  • 14
  • 29
14
votes
2 answers

Trouble with storing a type tag when implementing an std::variant-like class

My aim is to write std::variant, may be not full blown, but at least with fully working constructor/destructor pair and std::get<>() function. I tried to reserve a memory using char array. The size of it is determined by the biggest type, which is…
Incomputable
  • 2,188
  • 1
  • 20
  • 40
14
votes
3 answers

Why can't Delphi variants hold objects?

Why can't Delphi variants hold objects? More importantly, what's the reason behind this limitation?
utku_karatas
  • 6,163
  • 4
  • 40
  • 52
14
votes
1 answer

What is boost::variant memory and performance cost?

boost::variant seems a powerful container to manipulate a heterogeneous set of types. I am wondering its cost. In memory, I think it takes up the size of the largest type plus an integer representing which(). For apply_visitor(), I think its…
user1899020
  • 13,167
  • 21
  • 79
  • 154
13
votes
3 answers

What is the equivalent of boost::variant in the C++ standard library?

I am looking for an alternative to C-style union. boost::variant is one such option. Is there anything in std C++ ? union { int i; double d; }
cached
  • 569
  • 1
  • 7
  • 14
13
votes
3 answers

How can I convert from generic to Variant in Delphi

I have a Delphi generic class that exposes a function with an argument of the generic type. Inside this function, I need to pass an instance of the generic type on to another object expecting a Variant type. Similar to this: type IMyInterface =…
Mathias Falkenberg
  • 1,110
  • 1
  • 11
  • 25
13
votes
3 answers

How to stream std::variant<...,...>

My std::variant contains streamable types: std::variant a, b; a = 1; b = "hi"; std::cout << a << b << std::endl; Compiling with g++7 with -std=c++1z returns compilation time errors. An excerpt: test.cpp: In function 'int…
Tom
  • 3,281
  • 26
  • 33
13
votes
2 answers

Unsafe, `noexcept` and no-overhead way of accessing `std::variant`

std::variant provides the following access functions: std::get_if: take pointer to variant, return pointer to alternative. template auto* std::get_if(std::variant* pv) noexcept; If pv is not a null…
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
12
votes
5 answers

Why can I not retrieve the index of a variant and use that to get its content?

I'm trying to access the content of a variant. I don't know what's in there, but thankfully, the variant does. So I thought I'll just ask the variant what index it is on and then use that index to std::get its content. But this does not…
Alex
  • 3,316
  • 4
  • 26
  • 52
12
votes
3 answers

What does the "operator()..." syntax mean in C++?

I'm trying to understand the example of std::visit from cppreference, Where I saw the following line of code: template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) ->…
msc
  • 33,420
  • 29
  • 119
  • 214
12
votes
1 answer

C++17 variant inside the class

The following code compiles well: int main() { variant var; var = 5; cout << any_cast(get(var)) << endl; return 0; } But when I'm trying to put variant as a class member struct MyClass{ variant
Zak
  • 464
  • 3
  • 13
12
votes
1 answer

Modelling algebraic data types using relational database

Say you are writing an app in OCaml/F#/SML/Haskell and want to persist data in a relational database. It is easy to map product types (records and tuples) to relations, but how do you map variant types to relations? To be concrete, how would you…
Vladimir Keleshev
  • 13,753
  • 17
  • 64
  • 93
1 2
3
76 77