Много раз, во время разработки программы на C++, программисту необходимо манипулировать несколькими различными типами в единообразной манере. Действительно, C++ имеет прямую языковую поддержку для таких типов с помощью ключевого слова<union>:
union { int i; double d; } u;
u.d = 3.14;
u.i = 3; // overwrites u.d (OK: u.d is a POD type)
Конструкция C++<union>практически бесполезна в объектно-ориентированной среде. Конструкция вошла в язык прежде всего как средство для сохранения совместимости с C, которое поддерживает только типы POD (Plain Old Data) и поэтому не принимает типы, демонстрирующие нетривиальную конструкцию или разрушение:
union {
  int i;
  std::string s; // illegal: std::string is not a POD type!
} u;
Очевидно, требуется другой подход. Типичные решения характеризуются динамическим распределением объектов, которыми впоследствии манипулируют через общий базовый тип (часто виртуальный базовый классHen01) или, что более опасно,<void*>). Объекты бетонного типа могут быть затем извлечены посредством полиморфной нисходящей конструкции (например,<dynamic_cast>,<boost::any_cast>и т.д.).
Однако решения такого рода очень подвержены ошибкам из-за следующего:
- Ошибки сбрасывания не могут быть обнаружены во время компиляции.Таким образом, неправильное использование нисходящих конструкций приведет к ошибкам, обнаруживаемым только во время выполнения.
- Добавление новых конкретных типов может быть проигнорировано.Если к иерархии добавляется новый конкретный тип, существующий нисходящий код будет продолжать работать как есть, полностью игнорируя новый тип. Следовательно, программист должен вручную находить и изменять код в нескольких местах, что часто приводит к ошибкам времени выполнения, которые трудно найти.
Кроме того, даже при правильной реализации эти решения, как правило, несут относительно значительный штраф за абстракцию из-за использования кучи, вызовов виртуальных функций и полиморфных нисходящих потоков.
 
Solution: A Motivating Example
Шаблон класса<boost::variant>решает эти проблемы безопасным, простым и эффективным способом. Следующий пример показывает, как можно использовать класс:
#include "boost/variant.hpp"
#include <iostream>
class my_visitor : public boost::static_visitor<int>
{
public:
    int operator()(int i) const
    {
        return i;
    }
    
    int operator()(const std::string & str) const
    {
        return str.length();
    }
};
int main()
{
    boost::variant< int, std::string > u("hello world");
    std::cout << u; // output: hello world
    int result = boost::apply_visitor( my_visitor(), u );
    std::cout << result; // output: 11 (i.e., length of "hello world")
}