$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [Boost-users] [Boost 1.56 Beta] [Serialization] Compilation problem with classes having special new operators
From: Hijok Payne (hijokpayne_at_[hidden])
Date: 2014-07-28 16:17:07
The class specific new and delete operators in Eigen are implemented as
shown here
https://bitbucket.org/eigen/eigen/src/3c86e3d626c39de4616a32393f2c57594f9fb131/Eigen/src/Core/util/Memory.h?at=default#cl-697
(see lines 698-718). I see delete() operators corresponding to the new().
Is defining delete( void*, size_t ) a must requirement?
I am noob regarding c++ intricate memory details. And if this a problem on
Eigen's part, I can submit a bug report there.
On Fri, Jul 25, 2014 at 5:01 PM, Hijok Payne <hijokpayne_at_[hidden]> wrote:
> I was trying out the new Boost 1.56 beta and some of my serialization code
> fails to compile (they work fine with previous versions of Boost e.g. Boost
> 1.55).
>
> I am trying to do serialization of Eigen (http://eigen.tuxfamily.org/)
> matrices with following code:
>
> #include <Eigen/Core>
> #include <fstream>
> #include <boost/serialization/vector.hpp>
> #include <boost/archive/binary_oarchive.hpp>
> #include <boost/archive/binary_iarchive.hpp>
>
> //Boost Serialization of Eigen Matrix
> namespace boost {
>   template<class Archive, typename _Scalar, int _Rows, int _Cols, int
> _Options, int _MaxRows, int _MaxCols>
>   inline void serialize(Archive & ar,
>     Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& t,
>     const unsigned int file_version) {
>     size_t rows = t.rows(), cols = t.cols();
>     ar & rows;
>     ar & cols;
>     if (rows * cols != t.size())
>       t.resize(rows, cols);
>     ar & boost::serialization::make_array(t.data(), t.size());
>   }
> }
>
> //Simple helper for serialization to a file
> template <typename T>
> bool serialize(const T& data, const std::string& filename) {
>   std::ofstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
>   if (!ofs.is_open())
>     return false;
>   { // use scope to ensure archive goes out of scope before stream
>     boost::archive::binary_oarchive oa(ofs);
>     oa << data;
>   }
>   ofs.close();
>   return true;
> }
>
> //Simple helper for de-serialization from a file
> template <typename T>
> bool deSerialize(T& data, const std::string& filename) {
>   std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
>   if (!ifs.is_open())
>     return false;
>   { // use scope to ensure archive goes out of scope before stream
>     boost::archive::binary_iarchive ia(ifs);
>     ia >> data;
>   }
>   ifs.close();
>   return true;
> }
>
> int main(int argc, char *argv[]) {
>   typedef Eigen::Vector3d VectorType;
>   VectorType* vec = new VectorType(1, 2, 3);
>   serialize(vec, "v4d.dat");
>   std::cout << "v4d =\n" << *vec << std::endl;
>
>   VectorType* vec_in;
>   deSerialize(vec_in, "v4d.dat");
>   std::cout << "v4d_in =\n" << *vec_in << std::endl;
>   return 0;
> }
>
> The error in Visual studio 2013 says:
>
> boost/archive/detail/iserializer.hpp(237): error C2665:
> 'Eigen::PlainObjectBase<Eigen::Matrix<double,3,1,0,3,1>>::operator delete'
> : none of the 3 overloads could convert all the argument types
> 2>
>  c:\users\abhijit\codes\installs\eigen\eigen-install\include\eigen3\eigen\src/Core/PlainObjectBase.h(132):
> could be 'void
> Eigen::PlainObjectBase<Eigen::Matrix<double,3,1,0,3,1>>::operator
> delete(void *,const std::nothrow_t &) throw()'
> 2>
>  c:\users\abhijit\codes\installs\eigen\eigen-install\include\eigen3\eigen\src/Core/PlainObjectBase.h(132):
> or       'void
> Eigen::PlainObjectBase<Eigen::Matrix<double,3,1,0,3,1>>::operator
> delete(void *,void *) throw()'
> 2>          while trying to match the argument list '(VectorType *,
> size_t)'
> 2>
>  C:\Boost\boost-1_56_0_b1\boost/archive/detail/iserializer.hpp(224) : while
> compiling class template member function 'void
> boost::archive::detail::heap_allocation<T>::has_new_operator::invoke_delete(T
> *)'
>
> There is also the following note, but I cannot seem to understand this.
>
> // if compilation fails here, the likely cause that the class
> // T has a class specific new operator but no class specific
> // delete operator which matches the following signature.  Fix
> // your program to have this.  Note that adding operator delete
> // with only one parameter doesn't seem correct to me since
> // the standard(3.7.4.2) says "
> // "If a class T has a member deallocation function named
> // 'operator delete' with exactly one parameter, then that function
> // is a usual (non-placement) deallocation function" which I take
> // to mean that it will call the destructor of type T which we don't
> // want to do here.
>
> I want to understand this issue because this breaks a lot of existing code.
>
>
>