Проблема с ускорением сериализации 1.70 (с использованием shared_ptr) в Sun Studio 12.4

Я пытаюсь сериализовать несколько простых классов, используя полиморфизм и shared_ptr. Основным из моих тестов является следующее:

#include <iostream>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>

#include "classes.hpp"

namespace fs = boost::filesystem;

int main()
{
   try {
      fs::path filename("serialization.xml");
      {  // Serialiazing...
         boost::shared_ptr<Interface> c0 = createConcrete0(123.456);
         std::ofstream ofs(filename.string().c_str());
         boost::archive::xml_oarchive oa(ofs);

         std::cout << "[ser]   c0 size: " << c0->size() << std::endl;
         oa << BOOST_SERIALIZATION_NVP(c0);
      }

      {  // Deserialiazing...
         boost::shared_ptr<Interface> c0;

         std::ifstream ifs(filename.string().c_str());
         boost::archive::xml_iarchive ia(ifs);

         ia >> BOOST_SERIALIZATION_NVP(c0);

         std::cout << "[deser] c0 size: " << c0->size() << std::endl;
      }
   }
   catch(std::exception &e) {
      std::cout << "exception launch: " << e.what() << std::endl;
   }
   catch(...) {
      std::cout << "generic error" << std::endl;
   }

   return 0;
}

где classes.hpp - это:

// classes.hpp
#if !defined(_CLASSES_HPP__)
#define _CLASSES_HPP__

#include <boost/serialization/assume_abstract.hpp>
#include <boost/shared_ptr.hpp>

class Interface
{
public:
   virtual ~Interface() { }

   virtual size_t size() const = 0;
};

boost::shared_ptr<Interface> createConcrete0(double v);
boost::shared_ptr<Interface> createConcrete1(size_t sz);

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Interface);

#endif // _CLASSES_HPP__

и classes.cpp:

// classes.cpp
#include <iostream>
#include <boost/serialization/access.hpp>
#include <boost/serialization/nvp.hpp>
#include "classes.hpp"

class Concrete0: public Interface
{
public:
   Concrete0(): v_(0.0) { }
   Concrete0(double v): v_(v) { }

   size_t size() const { return 1; }

private:
   double v_;

   static bool registered;

   friend class boost::serialization::access;
   template<class Archive>
   void serialize(Archive &ar, const unsigned int)
   {
      boost::serialization::void_cast_register<Concrete0, Interface>(static_cast<Concrete0*>(NULL), static_cast<Interface*>(NULL));
      ar & BOOST_SERIALIZATION_NVP(v_);
   }
};

BOOST_SERIALIZATION_SHARED_PTR(Concrete0);

boost::shared_ptr<Interface> createConcrete0(double v)
{
   return boost::shared_ptr<Interface>(new Concrete0(v));
}

#include <boost/serialization/export.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>

BOOST_CLASS_EXPORT_KEY2(Concrete0, "Concrete0")
BOOST_CLASS_EXPORT_KEY2(Concrete1, "Concrete1")

BOOST_CLASS_EXPORT_IMPLEMENT(Concrete0)
BOOST_CLASS_EXPORT_IMPLEMENT(Concrete1)

template void Concrete0::serialize(boost::archive::xml_iarchive &ar, const unsigned int version);
template void Concrete0::serialize(boost::archive::xml_oarchive &ar, const unsigned int version);

И скомпилировав их с помощью CC и STLport, я получил следующий результат:

[ser]   c0 size: 1
Assertion failed: false, file libs/serialization/src/basic_serializer_map.cpp, line 103
Abort (core dumped)

Я пробовал тот же код с Sun Studio 12.3 и отлично работает. Единственный способ, который я нашел, заставить этот код работать, это изменить сериализацию следующим образом:

   template<class Archive>
   void serialize(Archive &ar, const unsigned int)
   {
      boost::serialization::void_cast_register<Concrete0, Interface>(static_cast<Concrete0*>(NULL), static_cast<Interface*>(NULL));
      ar.register_type<Concrete0>(NULL);
      ar & BOOST_SERIALIZATION_NVP(v_);
   }

Но мне это решение не очень нравится, потому что это означает, что мне нужно изменить много уже существующего кода.

Знаете ли вы какой-либо другой обходной путь без явного вызова метода архивации?

Спасибо, мирко

0 ответов

Другие вопросы по тегам