Cereal:如何管理PIMPL习惯用法的实现结构

时间:2016-08-01 01:59:04

标签: c++11 serialization visual-studio-2015 pimpl-idiom cereal

我在使用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上出现的错误:

  • C:\ Program Files(x86)\ Microsoft Visual Studio 14.0 \ VC \ include \ type_traits(428):错误C2139:&#39; BImpl&#39;:不允许将未定义的类作为参数编译器内在类型特征&#39; __ is_polymorphic&#39;

  • C:\ Program Files(x86)\ Microsoft Visual Studio 14.0 \ VC \ include \ type_traits(435):错误C2139:&#39; BImpl&#39;:不允许将未定义的类作为参数编译器内在类型特征&#39; __ is_abstract&#39;

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

1 个答案:

答案 0 :(得分:0)

我找到了遵循此处描述的方法的工作解决方案: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