Как сделать boost:: variant и boost:: любая работа?



Как вариант и любой из библиотеки boost работают внутри? В проекте, над которым я работаю, я в настоящее время использую помеченный Союз. Я хочу использовать что-то еще, потому что объединения в C++ не позволяют использовать объекты с конструкторами, деструкторами или перегруженными операторами присваивания.



Я запросил размер любого и варианта, и сделал некоторые эксперименты с ними. В моей платформе variant принимает размер своего самого длинного возможного типа плюс 8 байт: я думаю, что это мой просто 8 байт o тип информация и остальные данные. С другой стороны, любой просто занимает 8 байт. Поскольку я нахожусь на 64-битной платформе, я думаю, что любой просто держит указатель.



Как любой знает, какой тип он имеет? Как вариант добиться того, что он делает через шаблоны? Я хотел бы узнать больше об этих классах, прежде чем использовать их.

454   3  

3 ответов:

Если Вы читаете boost:: любая документация они предоставляют источник для идеи:http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf

это скрытие основной информации, необходимый навык C++. Учись этому!

поскольку самый высокий проголосованный ответ здесь совершенно неверен, и у меня есть сомнения в том, что люди действительно пойдут посмотреть на источник, чтобы проверить этот факт, вот базовая реализация любого подобного интерфейса, который будет оберните любой тип с помощью функции f () и позвольте ему быть вызванным:

struct f_any
{
   f_any() : ptr() {}
   ~f_any() { delete ptr; }
   bool valid() const { return ptr != 0; }
   void f() { assert(ptr); ptr->f(); }

   struct placeholder
   {
     virtual ~placeholder() {}
     virtual void f() const = 0;
   };

   template < typename T >
   struct impl : placeholder
   {
     impl(T const& t) : val(t) {}
     void f() const { val.f(); }
     T val;
    };
   // ptr can now point to the entire family of 
   // struct types generated from impl<T>
   placeholder * ptr;

   template < typename T >
   f_any(T const& t) : ptr(new impl<T>(t)) {}

  // assignment, etc...
};

boost:: any делает то же самое основное, за исключением того, что F() фактически возвращает typeinfo const& и предоставляет доступ к другой информации для работы функции any_cast.

ключевая разница между boost::any и boost::variant это any может хранить любой тип, в то время как variant может хранить только один из набора перечисленных типов. Элемент any тип хранит a void* указатель на объект, а также typeinfo объект для запоминания базового типа и обеспечения некоторой степени безопасности типа. В boost::variant, он вычисляет объект максимального размера и использует "размещение нового" для выделения объекта в этом буфере. Он также хранит тип или тип индекс.

обратите внимание, что если у вас установлен Boost, вы должны иметь возможность видеть исходные файлы в "any.ГЭС" и "вариант.ТЭЦ." Просто найдите "Включить/увеличить / вариант.ГЭС "и" включают / повышают / любые.hpp " в "/usr", "/usr/local" и "/opt / local", пока вы не найдете установленные заголовки, и вы можете посмотреть.

Edit
Как было указано в комментариях ниже, в моем описании boost::any была небольшая неточность. Пока это может быть реализовано с помощью void* (и шаблонный обратный вызов destroy для правильного удаления указателя), фактическая реализация использует any<T>::placeholder* С any<T>::holder<T> как подклассы any<T>::placeholder для унификации типа.

boost::any просто снапшоты typeinfo во время выполнения шаблонного конструктора: он имеет указатель на не шаблонный базовый класс, который предоставляет доступ к typeinfo, и конструктор получил класс, соответствующий этому интерфейсу. Тот же самый метод может фактически использоваться для захвата других общих возможностей набора типов (например, потоковая передача, общие операторы, конкретные функции), хотя boost не предлагает контроль над этим.

boost:: вариант концептуально похож что вы делали раньше, но не буквально с помощью union и вместо того, чтобы использовать ручной подход к созданию/уничтожению объектов размещения в своем буфере (при явной обработке проблем выравнивания), он работает вокруг ограничений, которые C++ имеет re сложные типы в фактическом union s.

Comments

    Ничего не найдено.