Skip to content

Latest commit

 

History

History
130 lines (92 loc) · 2.54 KB

tutorial_variant.md

File metadata and controls

130 lines (92 loc) · 2.54 KB

Tutorial for using Variant

metapp::Variant allows to store data of any type and convert between types.
Variant holds a single value of any type at the same time. The type can be any C++ type, such as int, class, std::string, std::vector, function pointer, etc, any type.

Include headers

Include the header for metapp::Variant

#include "metapp/variant.h"

To use all declared meta types, include this header

#include "metapp/allmetatypes.h"

Use Variant

v contains int.

metapp::Variant v(5);
ASSERT(v.get<int>() == 5);

We can get as reference, to avoid copy the value.

ASSERT(v.get<int &>() == 5);
ASSERT(v.get<const int &>() == 5);

We can even get as fancy const volatile reference.

ASSERT(v.get<const volatile int &>() == 5);

Now v contains std::string.

v = std::string("hello");

Get as std::string will copy the value, that's inefficient.

ASSERT(v.get<std::string>() == "hello");

We should get as reference to avoid copy.

ASSERT(v.get<const std::string &>() == "hello");

Whether the reference is const, it doesn't matter.

ASSERT(v.get<std::string &>() == "hello");

We can assign to the reference if it's not const.

v.get<std::string &>() = "world";
ASSERT(v.get<const std::string &>() == "world");

Now v contains char [].

v = "great";
ASSERT(strcmp(v.get<const char []>(), "great") == 0);

Cast to const char *.

metapp::Variant casted = v.cast<const char *>();
ASSERT(strcmp(casted.get<const char *>(), "great") == 0);

Cast to std::string.

casted = v.cast<std::string>();
ASSERT(casted.get<const std::string &>() == "great");

Let's see how Variant works with array

int array[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };

Now v contains reference to int[2][3]. We can't simply assign array to v because the array type will be lost. We need to call Variant::create or Variant::reference to retain the array type.

v = metapp::Variant::reference(array);
ASSERT(v.get<int (&)[2][3]>()[1][2] == 6);

Since v is a reference to array, modify array will also modify v

array[1][2] = 10;
ASSERT(v.get<int (&)[2][3]>()[1][2] == 10);

Now we copy array into v.

int anotherArray[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
v = anotherArray;
ASSERT(v.get<int (&)[2][3]>()[1][2] == 6);

Since v is a copy of anotherArray, modify anotherArray will not affect v.

anotherArray[1][2] = 10;
ASSERT(v.get<int (&)[2][3]>()[1][2] == 6);