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
7
votes
2 answers

How to specify colour for dark and light theme in general in VSCode user settings

I'd like to customize VSCode colour settings in general for dark or light theme variants, for example: "workbench.colorCustomizations": { "light": { "editor.background": "#ff0000", } } To my knowledge, however, it's only possible to…
7
votes
2 answers

Why am I getting "The type parameter must be invariantly valid..." error?

I'll attempt to shorten this code example: public interface IThing { //... Stuff } public class Thing1 : IThing { } public class Thing2 : IThing { } public interface IThingView { ICollection ViewAll(); } public class…
TheTFo
  • 741
  • 2
  • 8
  • 25
7
votes
2 answers

How to iterate over the types of std::variant?

I have some variant using V = std::variant and a function with the prototype V parse(const json&). The function should try to parse all the types (e.g. A, B, then C) till the first success (and it should do it implicitly, for there will be…
Nestor
  • 687
  • 5
  • 12
7
votes
2 answers

Android Gradle Plugin (Warning) API 'variant.getMergeResources()' is obsolete and has been replaced with 'variant.getMergeResourcesProvider()'

I am trying to build and run this repository augmented-images and I encounted this error. Caused by: java.lang.RuntimeException: Error creating sfa. Which drill down to this warning Warning ! API 'variant.getMergeResources()' is obsolete and has…
Cockpit Aliens
  • 411
  • 6
  • 18
7
votes
2 answers

Getting active value in std::visit without knowing which value is active

I want to get the active value in a std::variant without knowing which one is active. I thought i could write a template visitor and use std::visit but it doesn't work. #include #include #include struct…
Sandro4912
  • 313
  • 1
  • 9
  • 29
7
votes
1 answer

std::variant modification in constexpr

Consider the following two programs: #include #include constexpr auto f() { using T = std::variant; T t(false); t = T(true); return std::get(t); } template void print() { std::cout << V…
user10605163
7
votes
1 answer

Extensible state machines in Haskell

I can define a toy state machine (with trivial input) as follows: -------------------------------------------- -- module State where data State = A | B Int -------------------------------------------- -- module A where -- import State transitionA…
Sam Derbyshire
  • 719
  • 1
  • 4
  • 12
7
votes
0 answers

std::variant and move constructor Bug in GCC8

I have this piece of code that works really good in GCC7.2, clang 7 and MSVC, but not in GCC 8.0. Apparently, it deals with the copy constructor... #include #include #include #include struct…
Antoine Morrier
  • 3,930
  • 16
  • 37
7
votes
1 answer

VBA: how to null a Variant?

I have the following Variant: Dim comboitems() As Variant that I use in all the code as an array that contains the values of a ComboBox control. In a certain point of the code, I need to clear/empty/null comboitems(). How can I do? I tried all of…
user7867367
7
votes
4 answers

Variant visitation and common_type

I am wondering how std::visit return type conversions are supposed to work. The context is the following: I have a variant object and I want to apply (through std::visit) different functions depending on its underlying type. The result of each…
Bérenger
  • 2,678
  • 2
  • 21
  • 42
7
votes
2 answers

C++ - boost get question

Does someone know if the boost::get for the boost::variant is a performance-consuming operation or not. Right now I am refactoring some old code in a performance-critical part, where "varianting" was implementing by containers for each possible…
Yippie-Ki-Yay
  • 22,026
  • 26
  • 90
  • 148
7
votes
3 answers

Can Identifiers be duplicated across cases of a variant record in FreePascal?

Here's my problem: I want to create a record type where among the cases of a variant record, some, but not all, will have a certain field. According to the wiki, this is perfectly legal. And yet, when I tried to compile the following code: program…
junius
  • 570
  • 3
  • 14
7
votes
1 answer

reinterpret_cast / static_cast and undefined behavior

In a variant class I'm working on the raw storage is a char array: alignas(/* the strictest alignment of all types of the variant */) char storage[/* ... */]; The assignment operator is something like: template void operator=(const X…
manlio
  • 18,345
  • 14
  • 76
  • 126
7
votes
3 answers

What's the recommended implementation for hashing OLE Variants?

OLE Variants, as used by older versions of Visual Basic and pervasively in COM Automation, can store lots of different types: basic types like integers and floats, more complicated types like strings and arrays, and all the way up to IDispatch…
Barry Kelly
  • 41,404
  • 5
  • 117
  • 189
7
votes
1 answer

What is the difference between the VarIsEmpty and VarIsEmptyParam functions

Working in Delphi7 just now, I noticed that not only a VarIsEmpty function exists, but also a VarIsEmptyParam. Since the help of Delphi does not give much explanation: VarIsEmptyParam returns true if the given variant represents an unassigned …
Edelcom
  • 5,038
  • 8
  • 44
  • 61