Я пытаюсь включить C ++ 17 для нашей кодовой базы, основанной на boost - и boost :: serialization для промежуточного хранения данных и сериализации перед передачей.
В целом все выглядит хорошои, кажется, работает, за исключением случаев, когда мы сериализуем объекты Eigen :: Matrix и , включая заголовок поддержки расширенной сериализации для совместной сериализации ptr.
Минимальный пример / тестовый код на github: https://github.com/nightsparc/EigenSerialize
[EDIT] @Marc Glisse предоставил уменьшенный тестовый пример ниже.См .: https://stackoverflow.com/a/54536756/1267320
Я провел несколько тестов с разными компиляторами (GCC6 / 7/8 и Clang6).Мы обычно используем систему GCC, которая является GCC7.3 для Ubuntu 18.04.Для меня это, кажется, проблема, связанная с режимом C ++ 17 GCC7 и выше.
Я имею в виду, я не использую shared_ptr в минимальном примере, поэтому я могу удалить его, и все будет хорошо ... тем не менее, в нашей кодовой базе shared_ptrs везде сериализуются.
У кого-нибудь из вас есть идеи, что здесь происходит?Или это ошибка в режиме GCC C ++ 17?
Тестовый код (без надлежащей обработки ошибок и прочего ...):
#include <fstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/split_free.hpp>
#include <Eigen/Core>
// !! Conflicting include! Whenever the serialization wrapper for shared_ptrs is included
// the compilation fails!
// /usr/local/include/Eigen/src/Core/util/ForwardDeclarations.h:32:
// error: incomplete type ‘Eigen::internal::traits<boost::serialization::U>’ used in nested name specifier
// enum { has_direct_access = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0,
#include <boost/serialization/shared_ptr.hpp>
// Serialization methods for fixed-size Eigen::Matrix type
namespace boost {
namespace serialization {
template<
class Archive,
typename _Scalar,
int _Rows,
int _Cols,
int _Options,
int _MaxRows,
int _MaxCols
>
inline void serialize(Archive & arArchive,
Eigen::Matrix<_Scalar,
_Rows,
_Cols,
_Options,
_MaxRows,
_MaxCols> & arMatrix,
const unsigned int aVersion)
{
boost::serialization::split_free(arArchive, arMatrix, aVersion);
}
template<
class Archive,
typename _Scalar,
int _Rows,
int _Cols,
int _Options,
int _MaxRows,
int _MaxCols
>
inline void save(Archive & arArchive,
const Eigen::Matrix<_Scalar,
_Rows,
_Cols,
_Options,
_MaxRows,
_MaxCols> & arMatrix,
const unsigned int)
{
typedef typename Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Index TEigenIndex;
const TEigenIndex lRows = arMatrix.rows();
const TEigenIndex lCols = arMatrix.cols();
arArchive << lRows;
arArchive << lCols;
if(lRows > 0 && lCols > 0)
{
arArchive & boost::serialization::make_array(arMatrix.data(), arMatrix.size());
}
}
template<
class Archive,
typename _Scalar,
int _Rows,
int _Cols,
int _Options,
int _MaxRows,
int _MaxCols
>
inline void load(Archive & arArchive,
Eigen::Matrix<_Scalar,
_Rows,
_Cols,
_Options,
_MaxRows,
_MaxCols> & arMatrix,
const unsigned int)
{
typedef typename Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Index TEigenIndex;
TEigenIndex lRows, lCols;
// deserialize meta data
arArchive & lRows;
arArchive & lCols;
// do some error handling here
if(lRows > 0 && lCols > 0)
{
// deserialize data
arArchive & boost::serialization::make_array(arMatrix.data(), arMatrix.size());
}
}
}
}
class TestClass
{
public:
TestClass()
{
// fill eigen
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
}
private:
friend class boost::serialization::access;
Eigen::Matrix2d m;
template<class Archive>
void serialize(Archive &ar, const unsigned int)
{
ar & m;
}
};
int main(void)
{
using namespace boost::archive;
// Serialize
TestClass TestA;
std::ofstream oss("test.log");
{
text_oarchive oa(oss);
oa << TestA;
}
// deserialize now
TestClass TestB;
std::ifstream iss("test.log");
{
text_iarchive ia(iss);
ia >> TestB;
}
}
[РЕДАКТИРОВАТЬ 2019-02-06]
GCC-Bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84075
Eigen-Bug: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1676
[РЕДАКТИРОВАТЬ 2019-02-07]
Повышение PR: https://github.com/boostorg/serialization/pull/144