как повысить :: вариант и повысить :: любой работы?

<p>как вариант и любой из библиотеки boost работают внутри? в проекте, над которым я работаю, я использую теговый союз. я хочу использовать что-то еще, потому что объединения в c++ не позволяют использовать объекты с конструкторами, деструкторами или перегруженными операторами присваивания.</p><p>я запросил размер любого и варианта, и провел несколько экспериментов с ними. в моей платформе вариант принимает размер самого длинного из возможных типов плюс 8 байт: я думаю, что это всего лишь 8 байт информации о типе, а остальное - хранимое значение. с другой стороны, любой просто занимает 8 байтов. так как я на 64-битной платформе, я думаю, что любой просто держит указатель.</p><p>как кто-нибудь знает, какой тип он содержит? как variant достигает того, что он делает с помощью шаблонов? я хотел бы узнать больше об этих классах, прежде чем использовать их.</p>

<p>если вы читаете повышение :: любую документацию, они предоставляют источник идеи: <a href="http://www.two-sdg.demon.co.uk/curbralan/papers/valuedconversions.pdf">http://www.two-sdg.demon.co.uk/curbralan/papers/valuedconversions.pdf</a> </p><p>это скрытие базовой информации, необходимый навык c++. узнать его!</p><p>поскольку ответ с наибольшим количеством голосов здесь абсолютно неверен, и я сомневаюсь, что люди действительно пойдут посмотреть на источник, чтобы проверить этот факт, вот базовая реализация любого аналогичного интерфейса, который обернет любой тип f() и позволяют вызывать ее:</p><pre><code>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... }; </code></pre><p>boost :: any выполняет те же основные действия, за исключением того, что f() фактически возвращает <code>typeinfo const&</code> и предоставляет доступ к другой информации для работы функции any\_cast.</p>

<p>основное различие между <code>boost::any</code> и <code>boost::variant</code> заключается в том, что <code>any</code> может хранить любой тип, тогда как <code>variant</code> может хранить только один из набора перечислимых типов. тип <code>any</code> хранит указатель <code>void*</code> на объект, а также объект <code>typeinfo</code> для запоминания базового типа и обеспечения некоторой степени безопасности типов. в <code>boost::variant</code> он вычисляет объект максимального размера и использует "размещение нового" для размещения объекта в этом буфере. он также хранит тип или индекс типа.</p><p>обратите внимание, что если у вас установлен boost, вы сможете увидеть исходные файлы в "any.hpp" и "option.hpp". просто ищите "include/boost/variable.hpp" и "include/boost/any.hpp" в "/ usr", "/ usr/local" и "/ opt/local", пока не найдете установленные заголовки, и вы можете посмотреть.</p><p><b>правка</b><br> как было указано в комментариях ниже, в моем описании boost :: any была небольшая неточность. хотя это может быть реализовано с использованием <code>void*</code> (и шаблонного обратного вызова уничтожения для правильного удаления указателя), в действительности реализация использует <code>any<t>::placeholder*</code>, с <code>any<t>::holder<t></code> в качестве подклассов <code>any<t>::placeholder</code> для объединения типа.</p>

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