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