Boost :: serialization и boost :: mpi для трансляции производного класса через указатель базового класса

Я пытаюсь использовать boost :: mpi :: broadcast для отправки производного класса всем узлам через указатель базового класса. Для этого я использую библиотеку boost :: serialization для сериализации своих классов. Мой код, однако, не компилируется, и я получаю сообщения об ошибках: «класс boost :: mpi :: pack_skeleton_iarchive» не имеет члена с именем «append», а «class boost :: mpi :: pack_skeleton_iarchive» не имеет члена с именем «reset». «

Вот примерный исходный код программы:

// Base.hpp
#include <boost/serialization/serialization.hpp>

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

virtual void foo() = 0;
private:
friend class boost::serialization::access;

template<class Archive>
void serialize( Archive& /*ar*/, const unsigned int /*version*/ ) {}
}

// Derived.hpp
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/export.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>

#include "Base.hpp"
class Derived : public Base
{
public:
Derived( int param );
virtual ~Derived();

void foo();
private:
int param_;
std::vector< boost::shared_ptr > bar_;

friend class boost::serialization::access;

template<class Archive>
void serialize( Archive& ar, const unsigned int /*version*/ )
{
ar & param_;
ar & bar_;

ar & boost::serialization::base_object< Base >( *this );
}
}

namespace boost
{
namespace serialization
{
template<class Archive>
void load_construct_data( Archive& /*ar*/, Derived* d,
const unsigned int /*v*/ )
{
::new(d) Derived( 0 );
}
}
}

BOOST_CLASS_EXPORT_KEY( Derived )

// Derived.cpp
#include "Derived.hpp"
Derived::Derived( int param ) : param_( param ) {}
Derived::~Derived(){}

Derived::foo()
{
// some stuff
}

BOOST_CLASS_EXPORT_IMPLEMENT( Derived )

// Main.cpp
#include <boost/mpi.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/shared_ptr.hpp>

#include "Derived.hpp"
int main( int argc, char* argv[] )
{
boost::shared_ptr< Base > sp;

if ( world.rank() == 0 )
{
sp = boost::shared_ptr< Base >( new Derived( 5 ) );

boost::mpi::broadcast( world, sp, 0 );

// produce some stuff
} else
{
while ( 1 )
{
// consume some stuff
}
}

return 0;
}

BOOST_SERIALIZATION_ASSUME_ABSTRACT( Base )

Я нашел только одно обсуждение групп Google по этой проблеме, но пока нет решения https://groups.google.com/forum/#!msg/boost-developers-archive/Ee9_ilEDO7s/cJTy-8v5lEcJ. Как я могу получить это для компиляции? Я использую openmpi 1.2.8-17.4, gcc 4.5.1 и boost 1.54.

3

Решение

К счастью, я смог ответить на свой собственный вопрос (я думаю.) Boost не обрабатывает сериализацию по указателю базы должным образом в сочетании с boost :: mpi :: pack_skeleton_iarchive. Решение состоит в том, чтобы использовать другой вид архива, например, Вместо этого text_iarchive / text_oarchive.

Например, для трансляции:

std::ostringstream oss;
boost::archive::text_oarchive oa(oss);
oa << value;
std::string s = oss.str();
boost::mpi::broadcast(comm, s, root);

И получить:

std::string s;
boost::mpi::broadcast(comm, s, root);
std::istringstream iss(s);
boost::archive::text_iarchive ia(iss);
ia >> value;
1

Другие решения

Других решений пока нет …