I am tearing my hair out over this, partly because I believe the code used
to compile. I just can't see what the problem is. I enclose all the
pertinent code as I cannot say which bits are irrelevant.
There are two classes:
ManagedArray which is an array of data without size or capacity data
(this is stored elsewhere).
PersistentManagedArray which I wrote to enable ManagedArrays to be
serialized.
The error message is produced in 'main':
error: no match for 'operator<<' in 'oa << PersistentManagedArray<int>((*
& size), (* & capacity), (* & ints))'
It seems to me that I have defined the necessary serialize member function
with the right signature. Commented out is code I
wrote some time ago which used separate load and save functions. This, I
believe, used to work.
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <string>
using namespace std;
//****************************************************************************************************************************
template<class T>
class ManagedArray {
public:
T *values;
ManagedArray() {
values = NULL;
}
~ManagedArray() {
if (values) {
delete [] values;
}
}
//Changes array size. If array grows, the new values are unintialized.
void resize(unsigned oldSize, unsigned newSize) {
if (oldSize==newSize) return;
T *newValues = (newSize==0) ? NULL : new T[newSize];
if (oldSize!=0) {
T *oldValue, *newValue;
T *end = values + (oldSize<newSize ? oldSize : newSize);
for(oldValue=values, newValue=newValues; oldValue<end;
oldValue++, newValue++) {
*newValue = *oldValue;
}
}
if (values) {
delete [] values;
}
values = newValues;
}
//Changes array size. If array grows, the new values are
initialised to copies of a prototype, initValue.
void resize(unsigned oldSize, unsigned newSize, T &initValue) {
if (oldSize==newSize) return;
T *newValues = (newSize==0) ? NULL : new T[newSize];
T *oldValue = values;
T *newValue = newValues;
if (oldSize!=0) {
T *oldEnd = values + (oldSize<newSize ? oldSize : newSize);
for(; oldValue<oldEnd; oldValue++, newValue++) {
*newValue = *oldValue;
}
}
T *newEnd = newValues + newSize;
for(; newValue<newEnd; newValue++) {
*newValue = initValue;
}
delete [] values;
values = newValues;
}
inline T &operator[](unsigned index) {
return values[index];
}
inline const T &operator[](unsigned index) const {
return values[index];
}
};
//****************************************************************************************************************************
//This class helps to save a ManagedArray in a Boost archive
// Usage:
// ar & PersistentManagedArray(size, capacity, array);
template<class T>
class PersistentManagedArray {
public:
PersistentManagedArray(unsigned &size, unsigned &capacity,
ManagedArray<T> &managedArray) :
_size(size),
_capacity(capacity),
_managedArray(managedArray) {valueArrayExists =
(_managedArray.values!=NULL);}
private:
unsigned &_size;
unsigned &_capacity;
ManagedArray<T> &_managedArray;
bool valueArrayExists;
friend class boost::serialization::access;
// template<class Archive>
// void save(Archive & ar, const unsigned int version) const {
// ar & valueArrayExists;
// if (valueArrayExists) {
// for(unsigned i=0; i<_size; i++) {
// ar & _managedArray.values[i];
// }
// }
// }
// template<class Archive>
// void load(Archive & ar, const unsigned int version) {
// _managedArray.values = NULL;
// ar & valueArrayExists;
// if (valueArrayExists) {
// _managedArray.resize(0, _capacity);
// for(unsigned i=0; i<_size; i++) {
// ar & _managedArray.values[i];
// }
// }
// }
// BOOST_SERIALIZATION_SPLIT_MEMBER()
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & valueArrayExists;
ar & _size;
ar & _capacity;
if (Archive::is_loading::value) {
delete _managedArray.values;
_managedArray.values = new T[_capacity];
}
for(unsigned i=0; i<_size; i++) {
ar & _managedArray.values[i];
}
}
};
int main(int argc, char *argv[]) {
ManagedArray<int> ints;
unsigned size;
unsigned capacity;
string fileName = "data.xxx";
ofstream file(fileName.c_str(), ios::out|ios::binary);
if (file.good()) {
boost::archive::binary_oarchive oa(file);
oa << PersistentManagedArray<int>(size, capacity, ints); //This
line does not compile !
}
}