3

I am new in using boost serialization library.

I want to save and load data to and from STL structures using text_iarchive and text_oarchive.

On map, list, deque, set and vector there isn't any problem but on queue and stack I get following errors:

error: no matching function for call to 'save(boost::archive::text_oarchive&, const std::deque<PKT_UNIT, std::allocator<PKT_UNIT> >&, const unsigned int&)' 
error: no matching function for call to 'load(boost::archive::text_iarchive&, std::deque<PKT_UNIT, std::allocator<PKT_UNIT> >&, const unsigned int&)'

I used bellow code for that:

mystruct test;
test.initial();
{
    std::ofstream ofs("filename.dat");
    boost::archive::text_oarchive ar(ofs);
    ar & test;
}
{
    std::ifstream ifs("filename.dat");
    boost::archive::text_iarchive ar(ifs);
    mystruct restored;
    ar & restored;
}

How can I solve this problem?

sehe
  • 374,641
  • 47
  • 450
  • 633
samini
  • 195
  • 11

2 Answers2

3

Stack and queue aren't containers. They are container adaptors.

By design they don't expose raw access to the underlying container but the underlying containers are serializable standard library containers (vector<> and deque<>, by default respectively).

Boost serialization employs a trick with a derived class to get access to the underlying container ::c.

Due to technicalities surrounding the exact point-of-instantiation rules and ordering of templates, it is vital that the serialization code for the underlying containers is visible (declared) before the serialization code for the container adaptor.

In fact, clang has a very apt message here:

boost/serialization/queue.hpp|40 col 9| error: call to function 'save' that is neither visible in the template definition nor found by argument-dependent lookup

The problem, of course, being triggered by the fact that the load and save functions cannot be put with the containers in their declaring namespace, because that's the ::std namespace.

Fix

In the default cases, this means you need to include the serialization for deque before stack or queue:

#include <boost/serialization/deque.hpp>

#include <boost/serialization/stack.hpp>
#include <boost/serialization/queue.hpp>

Live On Coliru

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

#include <boost/serialization/deque.hpp>

#include <boost/serialization/stack.hpp>
#include <boost/serialization/queue.hpp>

struct mystruct {
    std::stack<int> _s;
    std::queue<int> _q;

    void foo() {
        _s.push(1); _s.push(2); _s.push(3);
        _q.push(1); _q.push(2); _q.push(3);
    }

    template <typename Ar> void serialize(Ar& ar, unsigned /*version*/) { ar & _s & _q; }
};

#include <fstream>

int main() {
    {
        mystruct test;

        std::ofstream ofs("filename.dat");
        boost::archive::text_oarchive oa(ofs);
        oa << test;
    }
    {
        std::ifstream ifs("filename.dat");
        boost::archive::text_iarchive ia(ifs);
        mystruct restored;
        ia >> restored;
    }
}

The filename.dat contains

 1  22 serialization::archive 15 0 0 0 0 0 0

in that live demo

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Many Thanks for your answer , yesterday I found out something first when I use cout for printing my structure it works Okey. but when I want to read and write from file this happens, this problem occurs only with use of stack and queue. At second, I used headers for serialization in main function before, but when I use that headers for my queue and stack class the problem solved. its wired !.. @sehe – samini Jan 28 '18 at 06:23
  • Can you show in code what you mean (just edit the live example, I guess. Perhaps use http://rextester.com if you need MSVC to reproduce the error). I think you're just getting the [POI](https://stackoverflow.com/questions/3866215/what-is-poi-and-what-does-it-mean) wrong. Alternatively you're using MSVC and they fail at it (they do fail at [2-phase name lookup](https://blogs.msdn.microsoft.com/vcblog/2017/09/11/two-phase-name-lookup-support-comes-to-msvc&)) – sehe Jan 28 '18 at 20:39
  • Oh, and [welcome to StackOverflow](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – sehe Jan 28 '18 at 20:40
  • I added a answer for you. @sehe – samini Jan 30 '18 at 06:25
  • @samini great! I got it now. My answer missed the whole point (of course I could have known had I checked the documentation, or if your question had included the code :)). I updated/fixed my answer. – sehe Jan 30 '18 at 08:59
  • I still have the problem on queue.hpp with Boost 1.80.0 and adding deque.hpp before solved the problem well, thanks. – Matthieu H Dec 04 '22 at 11:38
1

@sehe unfortunately I couldn't run my code on coliru viewer then I post it here. although it is simple to describe. when I used following order of header I got those two errors that mentioned on text_iarchive and text_oarchive for stack and queue structure :

#include <boost/serialization/vector.hpp>
#include <boost/serialization/set.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/queue.hpp>
#include <boost/serialization/stack.hpp>
#include <boost/serialization/deque.hpp>

But when I used this order problem solved

#include <boost/serialization/vector.hpp>
#include <boost/serialization/set.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/deque.hpp>
#include <boost/serialization/queue.hpp>
#include <boost/serialization/stack.hpp>
samini
  • 195
  • 11