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

A simple way to convert to/from VARIANT types in C++

Are there any easy-to-use, high-level classes or libraries that let you interact with VARIANTs in Visual C++? More specifically, I'd like to convert between POD types (e.g. double, long), strings (e.g. CString), and containers (e.g. std::vector)…
Nate Kohl
  • 35,264
  • 10
  • 43
  • 55
7
votes
1 answer

Convert Variant Array to String

I am trying to take a variant variable and convert it into a string so that I can run a split function on the data. However, whenever I try to redefine the variant I get a type mismatch error. I have used the CStr(), Str(), and ToString functions.…
user3428722
  • 71
  • 1
  • 1
  • 4
7
votes
2 answers

How to build a SAFEARRAY of pointers to VARIANTs?

I'm trying to use a COM component with the following method: HRESULT _stdcall Run( [in] SAFEARRAY(BSTR) paramNames, [in] SAFEARRAY(VARIANT *) paramValues ); How can I create in C/C++ the paramValues array?
Serge Weinstock
  • 1,235
  • 3
  • 12
  • 20
7
votes
1 answer

Pass data of arbitrary type between VBA and dll

So I am working on an Excel Project that is going to load a C++ dll using VBA. What I'd like to do is to be able to pass an Excel range with no specific type (data can be numerical or categorical) to the C++ dll (The best way I can describe my Excel…
SMir
  • 650
  • 1
  • 7
  • 19
6
votes
2 answers

Converting COM Object interface from C to Delphi

I am trying to convert the following two interfaces from a C header file to a Delphi PAS unit but have run into strange problems when using the ones I did myself. I need help understanding how to implement these in Delphi. Source interfaces from c…
TomRay74
  • 513
  • 6
  • 17
6
votes
1 answer

Boost variant get fail

I have such code: boost::variant
Max Frai
  • 61,946
  • 78
  • 197
  • 306
6
votes
4 answers

Converting value of type into Variant, is it possible?

here is a snippet showing what I am trying to achieve: type TMyObject = class (TObject) function GetVarType(Value: T): TVarType; end; function TMyObject.GetVarType(Value: T): TVarType; var TmpValue: Variant; begin TmpValue :=…
Wodzu
  • 6,932
  • 10
  • 65
  • 105
6
votes
1 answer

The advantage of std::visit over if-else

I have figured out that std::visit can be used the following way: std::visit([](auto&& arg) { using T = std::decay_t; if constexpr (std::is_same_v) std::cout << "int with value " << arg <<…
DottyPhone
  • 320
  • 1
  • 12
6
votes
1 answer

In OCaml, a variant declaring its tags with a colon

Looking at the following code: type z = Z of z type 'a s = Z | S of 'a type _ t = Z : z t | S : 'n t -> 'n s t the last line contains a generic variant, or what seems like one, but instead of using the keyword of it uses the colon symbol :. Why…
David 天宇 Wong
  • 3,724
  • 4
  • 35
  • 47
6
votes
1 answer

c++ : std::visit not compilable under gcc

Here is my code which compiles fine for clang but failed with gcc #include #include #include #include struct Id { void SetValue(const std::string& item) { value = item; } std::string…
Dmitry
  • 1,912
  • 2
  • 18
  • 29
6
votes
3 answers

C++ Variant visit overloaded function

I want to execute an overloaded function over a variant. The following code block works and compiles, but the visit invocation seems overly complex. Why can I not simply write: std::visit(&f, something); Working version and context: #include…
Hurricane Development
  • 2,449
  • 1
  • 19
  • 40
6
votes
1 answer

Calling RNGCrypto From COM's DOTNET Class From PHP

I'm attempting to call RNGCryptoServiceProvider->GetBytes() from PHP via the COM layer. I can get it to connect to the class, but every time I call the method, I get one of two errors (relating to the parameter). I think it has something to due…
ircmaxell
  • 163,128
  • 34
  • 264
  • 314
6
votes
2 answers

Sum types in C++

At work, I ran into a situation where the best type to describe the result returned from a function would be std::variant - of course, this isn't valid C++, because you can't have two variants of the same type. I could represent…
Kris Nuttycombe
  • 4,560
  • 1
  • 26
  • 29
6
votes
3 answers

std::variant cout in C++

I am relatively new to CPP and have recently stumbled upon std::variant for C++17. However, I am unable to use the << operator on such type of data. Considering #include #include #include using namespace std; int…
edvilme
  • 570
  • 7
  • 16
6
votes
1 answer

Serde internally tagged enum with common fields

I have the JSON roughly like this: [ { "commonA": 1, "commonB": 2, "type": "Foo", "fooSpecificA": 3, "fooSpecificB": 4 }, { "commonA": 5, "commonB": 6, "type": "Bar", "barSpecificA": 7, …
Timmmm
  • 88,195
  • 71
  • 364
  • 509