View source code
Display the source code in std/variant.d from which this page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone.

Module std.variant

This module implements a discriminated union type (a.k.a. tagged union, algebraic type). Such types are useful for type-uniform binary interfaces, interfacing with scripting languages, and comfortable exploratory programming.

A Variant object can hold a value of any type, with very few restrictions (such as shared types and noncopyable types). Setting the value is as immediate as assigning to the Variant object. To read back the value of the appropriate type T, use the get method. To query whether a Variant currently holds a value of type T, use peek. To fetch the exact type currently held, call type, which returns the TypeInfo of the current value.

In addition to Variant, this module also defines the Algebraic type constructor. Unlike Variant, Algebraic only allows a finite set of types, which are specified in the instantiation (e.g. Algebraic!(int, string) may only hold an int or a string).

Warning: Algebraic is outdated and not recommended for use in new code. Instead, use SumType.


Reviewed by Brad Roberts. Daniel Keep provided a detailed code review prompting the following improvements: (1) better support for arrays; (2) support for associative arrays; (3) friendlier behavior towards the garbage collector.


Variant a; // Must assign before use, otherwise exception ensues
// Initialize with an integer; make the type int
Variant b = 42;
writeln(b.type); // typeid (int)
// Peek at the value
assert(b.peek!(int) !is null && *b.peek!(int) == 42);
// Automatically convert per language rules
auto x = b.get!(real);

// Assign any other type, including other variants
a = b;
a = 3.14;
writeln(a.type); // typeid (double)
// Implicit conversions work just as with built-in types
assert(a < b);
// Check for convertibility
assert(!a.convertsTo!(int)); // double not convertible to int
// Strings and all other arrays are supported
a = "now I'm a string";
writeln(a); // "now I'm a string"

// can also assign arrays
a = new int[42];
writeln(a.length); // 42
a[5] = 7;
writeln(a[5]); // 7

// Can also assign class values
class Foo {}
auto foo = new Foo;
a = foo;
assert(*a.peek!(Foo) == foo); // and full type information is preserved


variantArray(args) Returns an array of variants constructed from args.


VariantException Thrown in three cases:


VariantN Back-end type seldom used directly by user code. Two commonly-used types using VariantN are:


tryVisit Behaves as visit but doesn't enforce that all types are handled by the visiting functions.
visit Applies a delegate or function to the given Algebraic depending on the held type, ensuring that all types are handled by the visiting functions.

Manifest constants

maxSize Gives the sizeof the largest type given.


Algebraic VariantN!(maxSize!T,T) Algebraic data type restricted to a closed set of possible types. It's an alias for VariantN with an appropriately-constructed maximum size. Algebraic is useful when it is desirable to restrict what a discriminated type could hold to the end of defining simpler and more efficient manipulation.
Variant VariantN!(32L) Alias for VariantN instantiated with the largest size of creal, char[], and void delegate(). This ensures that Variant is large enough to hold all of D's predefined types unboxed, including all numeric types, pointers, delegates, and class references. You may want to use VariantN directly with a different maximum size either for storing larger types unboxed, or for saving memory.


Andrei Alexandrescu


Boost License 1.0.