Cereal:如何管理 PIMPL 习语的实现结构

Cereal: how to manage the implementation struct for the PIMPL idiom

我在使用 cereal 和 PIMPL 习语时遇到问题。

这是一个最小的例子:

b.h

#ifndef _B_H_
#define _B_H_

#include <memory>
#include "cereal/types/memory.hpp"
#include "cereal/archives/json.hpp"

struct BImpl;

class B
{
public:
    B();
    ~B();

private:
    std::unique_ptr<BImpl> _impl;

    friend class cereal::access;

    template <class Archive>
    void serialize( Archive& ar )
    {
        ar( CEREAL_NVP( _impl ) );
    }
};

#endif

b.cpp

#include "b.h"

struct BImpl
{
     int b_i = 0;

private:
    friend class cereal::access;

    template <class Archive>
    void serialize( Archive & ar )
    {
        ar(
            CEREAL_NVP( b_i )
          );
    }
};

B::B() : _impl( new BImpl )
{
}

B::~B()
{
}

main.cpp

#include "b.h"
#include <fstream>
#include "cereal/archives/json.hpp"

using namespace std;

int main( int argc, char** argv )
{
    B b1;
    {
        std::ofstream file( "out.json" );
        cereal::JSONOutputArchive archive( file );
        archive( CEREAL_NVP( b1 ) );
    }
}

下面是我在 MSVC 2015 Community Edition 上尝试编译最小示例时遇到的错误:

我很确定我不是第一个尝试这样做的人,但我无法在 documentation 或代码片段中找到任何具体的工作解决方案。

我按照此处描述的方法找到了可行的解决方案:http://www.boost.org/doc/libs/1_46_1/libs/serialization/doc/pimpl.html

在实践中,我有: * 将 B::serialize 的定义移动到 B.cpp * 在 B.cpp 中添加了我使用的档案的所有不同实例

这里是描述问题的工单:https://github.com/USCiLab/cereal/issues/324