Брутально и бессердечно о программировании и проектировании
ГлавнаяФорумАртАнтипаттерныТест-драйвЗаметкиВопрос-ответКнигорецензииСправочная

Variant или any

«Variant» это такой объект-контейнер, в который можно поместить любой другой объект любого типа, а сами «варианты» можно сложить в массив, поскольку с точки зрения языка они явлются одним и тем же типом, независимо от того, что внутри них хранится. Помните наш мультфильм про Винни-пуха? «В нем можно держать все что угодно» — говорил Винни-пух про горшочек из-под меда. Аналогично, рассматриваемый паттерн позволяет в одном и том же объекте хранить значения любого типа. «Variant» это горшочек, в котором можно держать все что угодно.
 
Так все же, «Variant» или «Any»?

В разных языках этот механизм назывался и называется по-разному, при этом доля тех создателей языка, кто в своем языке назвал этот контейнер так-то только потому, что в языках, которые знал создатель, он назывался так же, довольно велика.

По скромному мнению автора, наиболее верно подобраны имена в библиотеке boost. boost::variant это объект-контейнер, который умеет хранить объекты из заранее определенного набора типов. boost::any это объект-контейнер, в который можно положить все что угодно, без каких-либо ограничений.
 
Рассмотрим одну из возможных реализаций паттерна «Variant». Данный паттерн можно реализовать большим количеством способов. Я придумал такой (хотя, с точки зрения буста, это все же any :-)
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <memory>
#include <string>

class variant
{
public:

    template <class T>
    variant& operator = (T const& t)
    {
        typedef type<T> assign_type;
        object = std::auto_ptr<assign_type>(new assign_type(t));
        return *this;
    }

    template <class T>
    operator T ()
    {
        typedef type<T> assign_type;
        assign_type& type = dynamic_cast<assign_type&>(*object);
        return type.get();
    }

private:

    class base
    {
    public:

        virtual ~base() {}
    };

    typedef std::auto_ptr<base> base_ptr;

    template <class T>
    class type : public base
    {
    public:

        type(T const& t)
        : object(t)
        {
        }

        T get() const
        {
            return object;
        }

    private:

        T object;
    };

    base_ptr object;
};

struct dummy
{
    int a;
    int b;
    int c;
};

int main()
{
    variant v1, v2, v3, v4;

    v1 = 2;
    v2 = 5.0f;
    v3 = std::string("Pot of gold");
    v4 = dummy();

    int         i = v1;
    float       f = v2;
    std::string s = v3;
    dummy       d = v4;

    return 0;
}
Пример довольно простой, но при этом он хорошо иллюстрирует все достоинства и недостатки данного паттерна.Винни-пух и день забот

Пустой горшочек — тоже variant!
Цель паттерна — предоставить возможность осуществлять единообразную работу с разнотипными данными. Например, эти разнотипные данные можно хранить в одном контейнере.
Основной недостаток — перенос контроля типов с compile-time-а на run-time.
Существуют ситуации, в которых данный паттерн может дать сиюминутное удобство. Однако, чаще всего за такое удобство впоследствии придется заплатить, так как воспользовавшись паттерном «Variant», пользователь освобождает компилятор от контроля типов и перетаскивает эту функцию на собственные плечи. Поэтому, если вдруг вы испытали потребность в этом паттерне, прежде всего задумайтесь, почему это произошло. Скорее всего найдется более безопасное и не менее изящное решение.
boost::any и boost::variant имеют более навороченную функциональность и, кроме того, более безопасны, чем мой вариант. Однако, и они не решают основную проблему — отсутствие возможности выполнить полноценную проверку типов на этапе компиляции.

Оглавление
Статистика
© 2007—2009 Inside C++ Коммерческие услугиКонтактная информация

квартира на сутки в гродно. аналоговые атс форум. Аккумуляторы свинцовые. Представляем вашему вниманию, компанию автоцентр сим - лучшая в Москве. сажите сотовый motorola хорош