Click here to Skip to main content
15,354,574 members
Articles / Programming Languages / C++
Posted 4 Jan 2005


28 bookmarked

Union Lists: Single Value, Multiple Types

Rate me:
Please Sign up or sign in to vote.
4.63/5 (16 votes)
20 Jan 20051 min read
A union list is a simple union style type which can hold one value of any of a fixed number of types.


A union list ( ul ) is a polymorphic type that can hold one value from one of the predetermined set of types. The precise type that a union list represents is determined at run-time when constructed based on the type of the value it is initialized with.


The primary role of a union list is to allow polymorphism between completely unrelated types. Unions have too many unreasonable limitations to be useful in most situations.

Using a Union List

A union list is declared recursively as follows:

ul<int, ul<char const*, ul_end> >

Note that the last element has to be of type ul_end. Usually we would use a union list with a typedef to save typing:

typedef ul<int, ul<char const*, ul_end> > IntOrString_T;

Declaring a variable of type ul requires an initializing value, such as:

IntOrString_T i(42);
IntOrString_T s("hello");

Once a ul is constructed, it provides the index of the type that it represents.

cout << i.TypeIndex() << endl; // outputs 0
cout << s.TypeIndex() << endl; // outputs 1

Of course, what is most important is accessing the data. This is done by passing the index of the type as a template parameter:

cout << i.Get<0>() << endl; // outputs 42
cout << s.Get<1>() << endl; // outputs "hello"

Of course, it can be a bit tricky to always correctly match the index passed to Get() with the correct internal data index, but don't worry, the union list will throw an exception if you make a mistake:

cout << i.Get<1>() << endl; // throws an exception

The Code

Here is the entire source code for the union list:

// public domain by Christopher Diggins, January 2005
// This is a utility class which allows the user to define a
// union of an arbitrary number of a list of types
struct ul_end {
  const TypeIndex() { return 0; }
template<typename Head_T, typename Tail_T, int N>
struct TypeList {
  typedef typename TypeList<
    typename Tail_T::H_T,
    typename Tail_T::T_T,
    N - 1>::type
template<typename Head_T, typename Tail_T>
struct TypeList<Head_T, Tail_T, 0> {
  typedef typename Head_T type;
template<typename Head_T, typename Tail_T>
struct ul
  typedef typename ul<Head_T, Tail_T> self;

  template<typename T>
  ul(T x) : tail(x), tag(false) { }

  ul(Head_T x) : head(x), tag(true) { }

  ul(const self& x) : head(x.head), tail(x.tail), tag(x.tag) { }

  ul() { };

  typedef typename Head_T H_T;
  typedef typename Tail_T T_T;

  Head_T head;
  Tail_T tail;
  bool tag;

  template<int N>
  typename TypeList<Head_T, Tail_T, N>::type& Get() {
    if (N != TypeIndex()) {
      throw 0;
    return *(TypeList<Head_T, Tail_T, N>::type*)InternalGet<N>();
template<int N>
void* InternalGet() {
   return tail.InternalGet<N-1>();
void* InternalGet<0>() {
  return &head;
const int TypeIndex() {
    return tag ? 0 : tail.TypeIndex() + 1;

Here is some example code to get you going:

#include <span class="code-keyword"><string></span>
#include <span class="code-keyword"><iostream></span>

using namespace std;
typedef ul<
> test_type;
void output(test_type x) {
  switch(x.TypeIndex()) {
    case 0 : cout << "int : " << x.Get<0>() << endl; break;
    case 1 : cout << "char : " << x.Get<1>() << endl; break;
    case 2 : cout << "bool : " << x.Get<2>() << endl; break;
    case 3 : cout << "float : " << x.Get<3>() << endl; break;
    case 4 : cout << "string : " << x.Get<4>() << endl; break;
int main() {
  output(string("Hello world"));
  return 0;


It would be preferable to have the TypeList type as a member template, as it would save a lot of scaffolding code, but unfortunately that is not portable across platforms. Member type template specializations are not part of the standard for some obscure reason.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Christopher Diggins
Software Developer Autodesk
Canada Canada
This article was written by Christopher Diggins, a computer science nerd who currently works at Autodesk as an SDK specialist.

Comments and Discussions

Questiongreat code Pin
Martial Spirit18-Mar-16 20:45
MemberMartial Spirit18-Mar-16 20:45 
GeneralElegant [modified] Pin
PlaceboZA4-Sep-06 3:43
MemberPlaceboZA4-Sep-06 3:43 
GeneralProblem with typelist recursion Pin
Hades_G20-Jan-05 3:32
MemberHades_G20-Jan-05 3:32 
GeneralRe: Problem with typelist recursion Pin
Christopher Diggins20-Jan-05 5:29
professionalChristopher Diggins20-Jan-05 5:29 
Generallooks similar with Loki's TypeList Pin
chenlee16-Jan-05 15:02
Memberchenlee16-Jan-05 15:02 
Generalul_end is not defined Pin
Hans14-Jan-05 7:23
MemberHans14-Jan-05 7:23 
GeneralRe: ul_end is not defined Pin
Hades_G20-Jan-05 4:15
MemberHades_G20-Jan-05 4:15 
GeneralRe: ul_end is not defined Pin
Christopher Diggins20-Jan-05 5:30
professionalChristopher Diggins20-Jan-05 5:30 
Mo Hossny13-Jan-05 6:28
MemberMo Hossny13-Jan-05 6:28 
Christopher Diggins20-Jan-05 5:30
professionalChristopher Diggins20-Jan-05 5:30 
GeneralThis is interesting !! Pin
WREY8-Jan-05 10:54
MemberWREY8-Jan-05 10:54 
GeneralRe: This is interesting !! Pin
Christopher Diggins20-Jan-05 5:46
professionalChristopher Diggins20-Jan-05 5:46 
GeneralVery Nice!! Pin
WREY20-Jan-05 9:41
MemberWREY20-Jan-05 9:41 
GeneralDo you have an idea... Pin
peterchen4-Jan-05 14:06
Memberpeterchen4-Jan-05 14:06 
GeneralRe: Do you have an idea... Pin
Christopher Diggins4-Jan-05 17:33
professionalChristopher Diggins4-Jan-05 17:33 
GeneralRe: Do you have an idea... Pin
Nemanja Trifunovic21-Jan-05 7:56
MemberNemanja Trifunovic21-Jan-05 7:56 
GeneralRe: Do you have an idea... Pin
.:floyd:.22-Jan-05 13:07
Member.:floyd:.22-Jan-05 13:07 
GeneralVery good Pin
Florian Heidenreich4-Jan-05 10:56
MemberFlorian Heidenreich4-Jan-05 10:56 
GeneralRe: Very good Pin
Christopher Diggins4-Jan-05 13:34
professionalChristopher Diggins4-Jan-05 13:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.