c++ 使用Boost.MPI将指向二维数组的指针序列化为类的成员

i5desfxk  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(138)

我有一个类,它的一个成员是一个指向二维整数数组的指针。我想在serialize函数中传递此成员,但收到以下错误:error: request for member ‘serialize’ in ‘t’, which is of non-class type ‘int’我读了documentation,我发现他们使用了

ar.register_type(static_cast<type *>(NULL));

所以我也做了同样的事但我还是有问题
我正在附加我试图序列化的代码段:

#include <iostream>
#include<set>
#include<map>
#include <boost/mpi/datatype.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>
#include <boost/mpi.hpp> 

class Dummy 
{
private: 
    int m_N;
    int** array; 
    friend class boost::serialization::access;
    template <class Archive>
    void serialize(Archive &ar, const unsigned int /*version*/)
    {
        ar &m_N; 
        ar.register_type(static_cast<int**>(NULL));
        ar &array; 
    }
public:
    Dummy(){}; 
    Dummy(const int N) 
    {
        m_N=N; 

        array = new int*[N+1];
        for(auto i=0;i<N+1;i++)
        {
            array[i] = new int[N+1];
        }
    };
    ~Dummy()
    {
        for(auto i=0;i<m_N+1;i++)
        {
            delete[]array[i];
        }delete[]array;
    }; 
    
};
namespace boost { namespace mpi {
    template <>
struct is_mpi_datatype<Dummy> : mpl::true_ { };
} }

int main(int argc, char* const argv[]) 
{
    boost::mpi::environment   env; 
    boost::mpi::communicator  world; 
    std::map<int,std::vector<Dummy>> IdToVecObject;
    std::vector<Dummy> vec; 
    std::set<int> neigbours; 
    if(world.rank()==0)
    {   
        Dummy obj(1); 
        vec.push_back(obj); 
        neigbours.insert(1); 
        IdToVecObject.emplace(1,vec); 

    }
    if(world.rank()==1)
    {
        Dummy obj(1); 
        vec.push_back(obj); 
        neigbours.insert(0); 
        IdToVecObject.emplace(0,vec); 
    }
    for(auto it:IdToVecObject)
    {
        int target= it.first;
        Dummy obj(1); 
        world.send(target,0,obj); 
    }
    for(auto i:neigbours)
    {
        int source= i ;  
        Dummy obj(1); 
        std::vector<Dummy> objects; 
        world.recv(source,0,obj); 
    }
    return 0; 
}
du7egjpx

du7egjpx1#

您的数组不是二维数组。它最多可以被描述为一个“规则的”锯齿状阵列。
register_type只与多态类型层次结构中的类型相关,所以这与C数组或int完全无关。
您需要序列化元素。最简单的方法是:

template <class Archive> void serialize(Archive& ar, unsigned) {
    ar& m_N;
    for (int i = 0; i<m_N; ++i)
        ar& boost::serialization::make_array(array[i], m_N);
}

呼呼

我忘了手动管理分配-这就是为什么你不使用C数组:

class Dummy {
  private:
    int   m_N     = 0;
    int** m_array = nullptr;

    friend class boost::serialization::access;

    template <class Archive> void serialize(Archive& ar, unsigned) {
        if /*constexpr*/ (Archive::is_saving) {
            ar& m_N;
        } else {
            int curN = m_N;
            ar& m_N;

            if (m_N > curN) // keep old allocation if big enough, optionally
                init();
        }

        for (auto* el : m_array)
            ar & boost::serialization::make_array(el, m_N);
    }

    void init() {
        if (m_array)
            destroy();
        m_array = new int*[m_N + 1];
        for (auto& el : m_array)
            el = new int[m_N + 1];
    }
    void destroy() {
        for (auto& el : m_array)
            delete[] el;
        delete[] m_array;
        m_array = nullptr;
    }

  public:
    Dummy(int N = 0) : m_N(N){ init(); };
    ~Dummy() { destroy(); };
};

(you可能需要#include <boost/serialization/array_wrapper.hpp>)。
更明智的方法是实际使用多维数组:https://stackoverflow.com/a/62109089/85371,或者至少像int[N][M]或更简单的int[N*M]那样连续存储它们。

相关问题