Boost :: вариант и получение данных для кодирования для MSGPACK - PullRequest
1 голос
/ 26 марта 2011

Я использую рекурсивный вариант boost для хранения данных варианта, которые я хочу кодировать, используя msgpack, для которого мне нужно получить необработанные данные для передачи в функцию encode () (см. Ниже).

Я попробовал три различных варианта в функции encode () ниже, но не работает. Какие альтернативы?

typedef std::vector<boost::recursive_variant_> vector_rvariant_t; 
typedef std::map<std::string, boost::recursive_variant_> map_rvariant_t;

typedef boost::make_recursive_variant <bool, boost::uint8_t, boost::uint32_t, 
        boost::int32_t, double, std::string, boost::uuids::uuid,  
        vector_rvariant_t, map_rvariant_t > ::type rvariant_type;

/**
 Wrapper class for boost::make_recuverise_variant<>::type
*/
class rvariant {
public:
   // encode the _data to msgpack buffer 
   //NEED HELP for this function.
    void encode(msgpack::sbuf& sbuf) {
       // msgpack::pack(sbuf, (*type_)data_);
       // msgpack::pack(sbuf, boost::get<typeid(data_)>(data_));
       // msgpack::pack(sbuf, boost::get<*type_>(data_));
    }

    // constructor 
    explicit template <typename T> rvariant(const T& data) {
       data_ = data;
       type_ =  (std::type_info*)&typeid(data);
    }

    // operator=  
   template <typename T> rvariant& operator=(const T& data) {
       data_ = data;
       type_ = (std::type_info*)&typeid(data);
       return *this;
   }

    // get the data 
   template<typename T> T get() {
       return boost::get< T >(data_);
   }

private:
  rvariant_type data_;
  std::type_info* type_;

};

1 Ответ

1 голос
/ 26 марта 2011

Я не думаю, что вы используете std::type_info таким образом, который работает с Boost :: Variant.

Идея:

  1. Используйте код, подобный приведенному здесь , чтобы обернуть ваши вызовы для кодирования вашего собственного тега. Используя посетителя, вы по существу ограничитесь открытым интерфейсом библиотеки Boost.Variant. Альтернатива: используйте variant.which

  2. Не пытайтесь отодвинуть внутреннюю пометку Boost :: Option и хранилище данных, так как это может измениться позже. Помните, что Boost.Variant может распределять свои внутренние данные по-разному в зависимости от функций компилятора и свойств параметров шаблона (например, ссылочные типы обрабатываются специально). Вместо этого кодируйте тег отдельно (как в первом шаге), а затем кодируйте (набранные) данные отдельно.

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

Редактировать: Я посмотрел на источник Boost.Serialization. Это может помочь: http://svn.boost.org/svn/boost/trunk/boost/serialization/variant.hpp

Редактировать: Чтобы проиллюстрировать (и сделать ответ более автономным), вот как выглядит посетитель в Boost.Serialization (см. Ссылку выше):

template<class Archive>
struct variant_save_visitor : boost::static_visitor<>  {
  variant_save_visitor(Archive& ar) : m_ar(ar) {}

  template<class T>
  void operator()(T const & value) const {
    m_ar << BOOST_SERIALIZATION_NVP(value);
  }
private:
  Archive & m_ar;
};
...