错误:不对应的“运营商的LT;<'使用boost ::系列化 [英] error: no match for 'operator<<' using boost::serialisation

查看:157
本文介绍了错误:不对应的“运营商的LT;<'使用boost ::系列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图得到一些(迄今)窗口code编译UNIX机器上,但我在下面的方法得到了一些错误:

I am trying to get some (hitherto) windows code to compile on a unix machine but am getting some errors at the following method:

namespace EDIN {
    void World::Save(char const filename[])                                                  
    {                                                                                        
        std::ofstream ofs(filename);                                                         

        boost::archive::text_oarchive oa(ofs);                                               

        oa << this << cellSequence << report; // line 590: error!
    }
}

错误看起来是这样的:

The error looks like this:

TEST.CPP:在成员函数'无效EDIN世界::保存(为const char *):
  TEST.CPP:122:12:错误:不对应的运营商的LT;&LT;'(操作数类型
  的boost ::存档:: text_oarchive的'和'EDIN ::全球*')
           OA&LT;&LT;该&lt;&LT; cellSequence&LT;&LT;报告; //行590:错误!
              ^ TEST.CPP:122:12:注意:候选人是:在从包含的文件
  /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/common_oarchive.hpp:22:0,
                   从/home/armanschwarz/lib/boost_1_55_0/boost/archive/basic_text_oarchive.hpp:32,
                   从/home/armanschwarz/lib/boost_1_55_0/boost/archive/text_oarchive.hpp:31,
                   从TEST.CPP:1:/home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/interface_oarchive.hpp:62:15:
  注意:归档和放大器;
  提高::档案::详细:: interface_oarchive ::运算&LT;&LT;(T&安培;)
  [与T = EDIN ::全球*;存档=的boost ::存档:: text_oarchive的]
       归档和放大器;运营商的LT;≤(T&amp; T公司){
                 ^ /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/interface_oarchive.hpp:62:15:
  注意:对于参数1从'EDIN ::全球*'没有已知的转换
  EDIN ::全球*放大器;

test.cpp: In member function ‘void EDIN::World::Save(const char*)’: test.cpp:122:12: error: no match for ‘operator<<’ (operand types are ‘boost::archive::text_oarchive’ and ‘EDIN::World*’) oa << this << cellSequence << report; // line 590: error! ^ test.cpp:122:12: note: candidate is: In file included from /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/common_oarchive.hpp:22:0, from /home/armanschwarz/lib/boost_1_55_0/boost/archive/basic_text_oarchive.hpp:32, from /home/armanschwarz/lib/boost_1_55_0/boost/archive/text_oarchive.hpp:31, from test.cpp:1: /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/interface_oarchive.hpp:62:15: note: Archive& boost::archive::detail::interface_oarchive::operator<<(T&) [with T = EDIN::World*; Archive = boost::archive::text_oarchive] Archive & operator<<(T & t){ ^ /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/interface_oarchive.hpp:62:15: note: no known conversion for argument 1 from ‘EDIN::World*’ to ‘EDIN::World*&’

我使用升压1.55.0(一样,当我用编译此有关的Visual Studio)。任何人都可以发现我在做什么错在这里?

I'm using boost 1.55.0 (same as when I used to compile this on Visual Studio). Can anyone spot what I'm doing wrong here?

下面是从sehe一个自包含的示例:

Here is a self-contained example from sehe:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/valarray.hpp>
#include <chrono>

namespace EDIN
{
    struct Region
    {
        int id;
        Region(int id = 42) : id(id) {}

      private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive & ar, const unsigned int file_version)
        {
            ar & id;
        }
    };

    struct Scheme
    {
        std::string GetSchemeType() const { return "scheme_type_42"; }
    };


    class World
    {
        // dummy members to make it compile
        // will be different things of course
        int mass, epoch;
        std::chrono::system_clock::time_point _start;

        std::string report;
      public:
        std::vector<int> cellSequence; // for demo, public

        World(std::string&, EDIN::Region&, unsigned int&, const std::chrono::system_clock::time_point&)
            : mass(99), epoch(88), _start(std::chrono::system_clock::now()), report("Report101")
        {
            // TODO!
        }

        Region       Bounds() const { return Region();       }
        int          Epoch()  const { return epoch;          }
        EDIN::Scheme Scheme() const { return EDIN::Scheme(); }
        std::chrono::system_clock::time_point StartingWallTime() const {
            return _start;
        }

        World()
            : mass(99), epoch(88), _start(std::chrono::system_clock::now()), report("Report101")
        {
        }

        void Save(char const filename[]);
        static World* Load(char const filename[]);

        private:
            friend class boost::serialization::access;
            template<class Archive> void serialize(Archive & ar, const unsigned int file_version)
            {
                ar & mass & epoch;
            }
    };
}

namespace boost
{
    namespace serialization
    {
        template<class Archive>
        inline void save_construct_data(Archive & ar, EDIN::World const * t, unsigned const int file_version)
        {
            time_t const totalRunningTime = std::chrono::duration_cast<std::chrono::duration<time_t, std::milli>>(
                std::chrono::system_clock::now() - t->StartingWallTime()).count();

            EDIN::Region const bounds = t->Bounds();
            time_t const epoch = t->Epoch();

            std::string tmp = t->Scheme().GetSchemeType();
            ar
                << bounds
                << epoch
                << totalRunningTime 
                << tmp;
        }

        template<class Archive>
        inline void load_construct_data(Archive & ar, EDIN::World * t, const unsigned int file_version)
        {
            EDIN::Region bounds;
            unsigned epoch;
            time_t totalRunningTime;
            std::string schemeType;
            ar >>
                bounds >>
                epoch >>
                totalRunningTime >>
                schemeType;

            std::chrono::system_clock::time_point const startingWallTime =
                std::chrono::system_clock::now() - std::chrono::duration<time_t, std::milli>(totalRunningTime);

            ::new(t) EDIN::World(schemeType,bounds,epoch,startingWallTime);
        }
    }
}

#include <fstream>

namespace EDIN {
    void World::Save(char const filename[])
    {
        std::ofstream ofs(filename);

        boost::archive::text_oarchive oa(ofs);

        oa << this << cellSequence << report; // line 590: error!
    }

    World* World::Load(char const filename[])
    {
        World *world = 0;

        std::ifstream ifs("world.save");
        boost::archive::text_iarchive ia(ifs);

        ia >> world;
        ia >> world->cellSequence >> world->report;

        return world;
    }
}

int main()
{
    EDIN::World world;
    world.cellSequence.push_back(12345);
    world.cellSequence.push_back(-6767);
    world.Save("world.save");

    EDIN::World* restored = EDIN::World::Load("world.save");
    restored->Save("world2.save");

    delete restored;
}

编译罚款这里使用GCC 4.8.1和Boost 1.55.0。我使用GCC 4.9.0,促进1.55.0。

It compiles fine here using GCC 4.8.1 and Boost 1.55.0. I am using GCC 4.9.0 and boost 1.55.0.

编辑:我发现,似乎工作黑客攻击:

这个问题似乎是,G ++ 4.9并不想投世界::这个世界* 世界*放大器; 。更换世界::保存方法,以下解决此问题:

The problem seems to be that G++ 4.9 doesn't want to cast World::this from World* to World*&. Replacing the World::Save method with the following resolves the problem:

void World::Save(char const filename[])
{
    std::ofstream ofs(filename);

    boost::archive::text_oarchive oa(ofs);

    World* thisCopy = this;
    oa << thisCopy << cellSequence << report;
}

有似乎是GCC 4.8.1和GCC 4.9之间的行为差​​异,导致后者无法编译,除非我创建这个指针的副本。如果有人能指出为什么发生这种情况以及是否是一个错误或行为意图的变化,这将是AP preciated!

There seems to be a difference in behaviour between GCC 4.8.1 and GCC 4.9 that causes the latter not to compile unless I create copy of the this pointer. If someone could point out why this is happening and whether or not it's a bug or intended change in behaviour that would be appreciated!

推荐答案

您没有给所有必要的信息。

You are not giving all the information necessary.

下面是根据样本code一个自包含的例子中,你/没有/显示

Here's a self-contained example based on the sample code you /did/ show

正如你所看到的,它运行良好。唯一的显著编辑我认为这可能会造成麻烦的是这些:

As you can see, it runs fine. The only significant edits I think that may be causing trouble are these:

std::string tmp = t->Scheme().GetSchemeType();
ar
    << bounds
    << epoch
    << totalRunningTime 
    << tmp;

// and the following (use of this as mutable reference, which some versions of GCC erronously accepted)

void SaveWorld(World* world, char const filename[])
{
    std::ofstream ofs(filename);
    boost::archive::text_oarchive oa(ofs);
    oa << world << world->cellSequence << world->report; // line 590: error!
}

麻烦的是,返回的按价值计算,的的由常量和放大器; ,因为 T 指针也正是在这种背景下常量。然而, AR&LT;&LT; 需要一个非const引用** [1] **,所以它不应该编译

The trouble is that returns either by value, or by const&, because the t pointer is also const in this context. However, ar << requires a non-const references**[1]**, so it should not compile.

原因MSVC可能已经接受了它,然而,可能是因为MSVC有一个(恶)非标准的扩展,它的扩展临时,当绑定到一个非const引用的的寿命。

The reason MSVC might have accepted it, nonetheless, could be because MSVC has an (evil) non-standard extension that extends lifetimes of temporaries, when bound to a non-const reference.

我的演示应用程序显示了序列化和反序列化在行动:

My demo app shows serialization and deserialization in action:

int main()
{
    using namespace EDIN;
    std::unique_ptr<World> world(new World);

    world->cellSequence.push_back(12345);
    world->cellSequence.push_back(-6767);
    SaveWorld(world.get(), "world.save");

    world.reset(LoadWorld("world.save"));
    SaveWorld(world.get(), "world2.save");
}

和您可以验证 world.save world2.save 最终成为自己相同(也 coliru )。

And you can verify that world.save and world2.save end up being identical for yourself (also on coliru).

全部SSCCE code,以供参考:

Full SSCCE code for reference:

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/valarray.hpp>
#include <chrono>
#include <memory>

namespace EDIN
{
    struct Region
    {
        int id;
        Region(int id = 42) : id(id) {}

      private:
        friend class boost::serialization::access;
        template<class Archive> void serialize(Archive & ar, const unsigned int file_version)
        {
            ar & id;
        }
    };

    struct Scheme
    {
        std::string GetSchemeType() const { return "scheme_type_42"; }
    };


    class World
    {
        // dummy members to make it compile
        // will be different things of course
        int mass, epoch;
        std::chrono::system_clock::time_point _start;

        std::string report;
      public:
        std::vector<int> cellSequence; // for demo, public

        World(std::string&, EDIN::Region&, unsigned int&, const std::chrono::system_clock::time_point&)
            : mass(99), epoch(88), _start(std::chrono::system_clock::now()), report("Report101")
        {
            // TODO!
        }

        Region       Bounds() const { return Region();       }
        int          Epoch()  const { return epoch;          }
        EDIN::Scheme Scheme() const { return EDIN::Scheme(); }
        std::chrono::system_clock::time_point StartingWallTime() const {
            return _start;
        }

        World()
            : mass(99), epoch(88), _start(std::chrono::system_clock::now()), report("Report101")
        {
        }

        friend void SaveWorld(World* world, char const filename[]);
        friend World* LoadWorld(char const filename[]);

        private:
            friend class boost::serialization::access;
            template<class Archive> void serialize(Archive & ar, const unsigned int file_version)
            {
                ar & mass & epoch;
            }
    };
}

namespace boost
{
    namespace serialization
    {
        template<class Archive>
        inline void save_construct_data(Archive & ar, EDIN::World const * t, unsigned const int file_version)
        {
            time_t const totalRunningTime = std::chrono::duration_cast<std::chrono::duration<time_t, std::milli>>(
                std::chrono::system_clock::now() - t->StartingWallTime()).count();

            EDIN::Region const bounds = t->Bounds();
            time_t const epoch = t->Epoch();

            std::string tmp = t->Scheme().GetSchemeType();
            ar
                << bounds
                << epoch
                << totalRunningTime 
                << tmp;
        }

        template<class Archive>
        inline void load_construct_data(Archive & ar, EDIN::World * t, const unsigned int file_version)
        {
            EDIN::Region bounds;
            unsigned epoch;
            time_t totalRunningTime;
            std::string schemeType;
            ar >>
                bounds >>
                epoch >>
                totalRunningTime >>
                schemeType;

            std::chrono::system_clock::time_point const startingWallTime =
                std::chrono::system_clock::now() - std::chrono::duration<time_t, std::milli>(totalRunningTime);

            ::new(t) EDIN::World(schemeType,bounds,epoch,startingWallTime);
        }
    }
}

#include <fstream>

namespace EDIN {
    void SaveWorld(World* world, char const filename[])
    {
        std::ofstream ofs(filename);

        boost::archive::text_oarchive oa(ofs);

        oa << world << world->cellSequence << world->report; // line 590: error!
    }

    World* LoadWorld(char const filename[])
    {
        World *world = 0;

        std::ifstream ifs("world.save");
        boost::archive::text_iarchive ia(ifs);

        ia >> world;
        ia >> world->cellSequence >> world->report;

        return world;
    }
}

int main()
{
    using namespace EDIN;
    std::unique_ptr<World> world(new World);

    world->cellSequence.push_back(12345);
    world->cellSequence.push_back(-6767);
    SaveWorld(world.get(), "world.save");

    world.reset(LoadWorld("world.save"));
    SaveWorld(world.get(), "world2.save");
}


[1] 技术原因不明,超出范围此处


[1] For obscure technical reasons, beyond the scope here

这篇关于错误:不对应的“运营商的LT;&LT;'使用boost ::系列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆