如何让boost :: serialization工作?

时间:2014-01-16 07:24:39

标签: c++ boost cmake ubuntu-12.04 boost-serialization

我正在使用ubuntu 12.04LTS并使用clang 3.4。

我有一个CMake项目,想要使用boost序列化库。我从SourceForge下载了boost 1.55.0。

我的项目文件夹树如下所示:

MyProject
    |    Source
    |       |    main.cpp
    |       |    CMakeLists.txt
    |    Build
    |    Libraries
    |       |    Boost1p55p0
    |       |         |    boost
    |       |         |    ...other boost data
    |       |         |    build
    |       |         |       |    include
    |       |         |       |    lib

所以在Boost1p55p0目录中我创建了一个新目录build,所以bootstrap看起来像:

./bootstrap.sh --prefix=build/

然后我做了

./b2

./b2 install

所以最小的不工作的例子是:

的CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)

set( CMAKE_C_COMPILER clang )
set( CMAKE_CXX_COMPILER clang++ )
set( CMAKE_LINKER llvm-link )

project (Test)
include_directories( ${PROJECT_SOURCE_DIR} ../Libraries/Boost1p55p0/build/include )

set( sources ${sources} main )

add_executable(Test ${sources})

set( OperatingSystem "Linux" )
set( CMAKE_CXX_FLAGS "-std=c++11" )

find_library( PATH_TO_BoostSerialization boost_serialization ../Libraries/Boost1p55p0/build/lib/ )

target_link_libraries (Test ${PATH_TO_BoostSerialization})

main.cpp(来自tutorial,但有xml档案):

#include <fstream>
#include <string>

// include headers that implement a archive in simple text format
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

/////////////////////////////////////////////////////////////
// gps coordinate
//
// illustrates serialization for a simple type
//
class gps_position
{
    private:
        friend class boost::serialization::access;

        template<class Archive>
        void serialize(Archive & ar, const unsigned int version)
        {
            ar & degrees;
            ar & minutes;
            ar & seconds;
        }
        int degrees;
        int minutes;
        float seconds;
    public:
        gps_position(){};
        gps_position(int d, int m, float s) :
            degrees(d), minutes(m), seconds(s){}
};

int main() {
    std::string inFileName = "testIn.xml";
    std::string outFileName = "testOut.xml";
    // create and open a character archive for output
    std::ofstream ofs(outFileName);

    // create class instance
    const gps_position g(35, 59, 24.567f);

    // save data to archive
    {
        boost::archive::xml_oarchive oa(ofs);
        // write class instance to archive
        oa << g;
    }

    return 0;
}

现在我收到以下编译器错误:

[cut off directory tree here]Boost1p55p0/build/include/boost/archive/basic_xml_oarchive.hpp:92:9: error: no matching function for call to
  'assertion_failed'
    BOOST_MPL_ASSERT((serialization::is_wrapper< T >));
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[cut off directory tree here]Boost1p55p0/build/include/boost/mpl/assert.hpp:287:11: note: expanded from macro 'BOOST_MPL_ASSERT'
      boost::mpl::assertion_failed<false>( \

我不知道错误在哪里。如果我知道的话,我很沮丧。

非常感谢提前

1 个答案:

答案 0 :(得分:5)

啊,我刚才注意到你在这里提到了唯一这个重要的位,隐藏在一个小的旁边:

  

main.cpp(来自教程,但有xml档案)

Xml存档需要名称作为其元素!

  

Name-Value Pairs

     

XML档案提供了一些特殊情况。 XML格式具有嵌套结构,可以很好地映射到序列化系统使用的“递归类成员访问者”模式。但是,XML与其他格式的不同之处在于它需要每个类数据成员的名称。我们的目标是将此信息添加到类序列化规范中,同时仍允许序列化代码与任何归档一起使用。

     

我们的解决方案是将类成员包装在名称 - 值对中进行序列化。该结构在nvp.hpp中定义。它只是对数据成员的引用,该数据成员与指向对应于XML名称的const char *的指针相结合。它实现了名称 - 值对的默认序列化功能。此默认操作是忽略项目名称并以正常方式序列化数据值。对于不对名称 - 值对进行任何特殊设置的归档类,这是在序列化名称 - 值对时将调用的操作。因此,将数据值包装到名称 - 值对中时,如果与对此包装器没有特殊规定的存档一起使用将不起作用。

请参阅demo_xml.cpp,添加:

template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
    ar & BOOST_SERIALIZATION_NVP(degrees);
    ar & BOOST_SERIALIZATION_NVP(minutes);
    ar & BOOST_SERIALIZATION_NVP(seconds);
}

boost::archive::xml_oarchive oa(ofs);
// write class instance to archive
oa << BOOST_SERIALIZATION_NVP(g);

查看 Live on Coliru

输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<g class_id="0" tracking_level="0" version="0">
    <degrees>35</degrees>
    <minutes>59</minutes>
    <seconds>24.566999</seconds>
</g>
</boost_serialization>