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

Is there a variadic template variant with a multi visitation method?

I hit the limit of 50 types in boost::variant. I found this nice self-contained header but it lacks the multi visitation feature (I actually need the double visitation). I tried to look a bit after it but such method seems very ambitious and clashes…
DarioP
  • 5,377
  • 1
  • 33
  • 52
10
votes
3 answers

Does using single-case discriminated union types have implications on performance?

It is nice to have a wrapper for every primitive value, so that there is no way to misuse it. I suspect this convenience comes at a price. Is there a performance drop? Should I rather use bare primitive values instead if the performance is a…
Trident D'Gao
  • 18,973
  • 19
  • 95
  • 159
10
votes
2 answers

Boost.Variant Vs Virtual Interface Performance

I'm trying to measure a performance difference between using Boost.Variant and using virtual interfaces. For example, suppose I want to increment different types of numbers uniformly, using Boost.Variant I would use a boost::variant over int and…
Tal Zion
  • 1,331
  • 2
  • 14
  • 23
9
votes
2 answers

boost::variant conversion to type

I have the following variant from the boost lib: typedef boost::variant variant; Now I want to get a value from a variable declared as 'value' in a struct node, so I thought I…
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
9
votes
4 answers

boost::variant to std::string

I have a boost variant of looking like this: typedef boost::variant variant; I have a need for being able to convert any of the values in this variant to a std::string, I…
Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
9
votes
1 answer

Recursively visiting an `std::variant` using lambdas and fixed-point combinators

I would like to visit a "recursive" std::variant using lambdas and overload-creating functions (e.g. boost::hana::overload). Let's assume I have a variant type called my_variant which can store one an int, a float or a vector: struct…
Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416
9
votes
1 answer

COM, VARIANT containing BSTR. Who allocates?

OK, so I couldn't really think of an apropos title that summarizes this. The IPrintPipelinePropertyBag interface has the method AddProperty which aptly enough "adds a property to a property…
moogs
  • 8,122
  • 8
  • 44
  • 60
9
votes
2 answers

What's the syntax for including methods in a variant record?

I have the following record definition E3Vector3T = packed record public x: E3FloatT; y: E3FloatT; z: E3FloatT; function length: E3FloatT; function normalize: E3Vector3T; function crossProduct( const aVector:…
Paul-Jan
  • 16,746
  • 1
  • 63
  • 95
9
votes
1 answer

Why does assigning a single to a variant result in a varDouble variant?

uses SysUtils, Variants; var VariantSingle: Variant; VTSingle: TVarType; SingleTest: Single; VariantDouble: Variant; DoubleTest: Double; VTDouble: TVarType; begin SingleTest := 1.234; VariantSingle := SingleTest; VTSingle :=…
TmTron
  • 17,012
  • 10
  • 94
  • 142
8
votes
3 answers

How to write an array tag in a VARIANT structure on an OpenOPC server

I'm trying to communicate with an OPC DA server and need to write in a tag which is in an array format. We can connect with a simulation server, read tags (int, real, array) and write tags (int, real, str). The problem comes when we need to write in…
Simon F.-Smith
  • 781
  • 3
  • 8
8
votes
2 answers

Using enums for dynamic polymorphism in Rust

When one already knows all the finite number of types involved in some code which needs dynamic polymorphism, using enum can be better for performances compared to using Box since the latter uses dynamic memory allocation and you'll need to use…
nyarlathotep108
  • 5,275
  • 2
  • 26
  • 64
8
votes
1 answer

g++ std::visit leaking into global namespace?

I just bounced into something subtle in the vicinity of std::visit and std::function that baffles me. I'm not alone, but the only other folks I could find did the "workaround and move on" dance, and that's not enough for…
8
votes
4 answers

boost::variant usage

I am developing GUI application via wxWidgets. It has 2 parts: GUI part and "Logic" part. I want to have Logic part totally independent on wxWidgets. But one component in the GUI returning wxVariant and I need to use it in the Logic part. So I am…
relaxxx
  • 7,566
  • 8
  • 37
  • 64
8
votes
1 answer

noexcept visitation for std::variant

For some standard library classes, access to parts of their contents may legitimately fail. Usually you have the choice between some potentially throwing method an one that is marked noexcept. The latter spares the check on the precondition, so if…
Tobi
  • 2,591
  • 15
  • 34
8
votes
3 answers

Can I avoid explicitly writing a constructor for each struct in a std::variant?

Consider this code: #include struct x { int y; }; int main() { std::variant v(std::in_place_type, {3}); /*1*/ return std::get(v).y; } This does not compile and neither does when removing the {} from the line /*1*/, even…
The Vee
  • 11,420
  • 5
  • 27
  • 60