title: Eigen Matrix + Boost::Serialization / C++17
body: <p>I'm trying to enable C++17 for our code base which is strongly based on boost - and boost::serialization for intermediate data storage and pre-transmission serialization.</p>
  
  <p>Overall, everything looks fine and seems to be working, except when we're serializing Eigen::Matrix objects <strong>and</strong> include the boost serialization support header for shared ptr serialization.</p>
  
  <p>Minimal example/testcode on github: <a href="https://github.com/nightsparc/EigenSerialize" rel="nofollow noreferrer">https://github.com/nightsparc/EigenSerialize</a></p>
  
  <p>[EDIT] @Marc Glisse provided a reduced testcase down below. See: <a href="https://stackoverflow.com/a/54536756/1267320">https://stackoverflow.com/a/54536756/1267320</a></p>
  
  <p>I did some tests with different compilers (GCC6/7/8 and Clang6). We're normally using the system GCC which is GCC7.3 for Ubuntu 18.04. 
  For me, it seems to be a problem related with the C++17 mode of GCC7 and higher. </p>
  
  <p>I mean, I'm not using a shared_ptr in the minimal example, so I could remove it and everything would be fine...nevertheless, in our codebase shared_ptrs get serialized everywhere.</p>
  
  <p>Does one of you guys have any idea whats going on here? Or is it a bug in GCC C++17 mode?</p>
  
  <p>The test code (without proper error handling and stuff...):</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;fstream&gt;
  
  #include &lt;boost/archive/text_iarchive.hpp&gt;
  #include &lt;boost/archive/text_oarchive.hpp&gt;
  #include &lt;boost/serialization/split_free.hpp&gt;
  
  #include &lt;Eigen/Core&gt;
  
  // !! 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&lt;boost::serialization::U&gt;’ used in nested name specifier
  // enum { has_direct_access = (traits&lt;Derived&gt;::Flags &amp; DirectAccessBit) ? 1 : 0,
  #include &lt;boost/serialization/shared_ptr.hpp&gt;
  
  // Serialization methods for fixed-size Eigen::Matrix type
  namespace boost {
      namespace serialization {
          template&lt;
                  class Archive,
                  typename _Scalar,
                  int _Rows,
                  int _Cols,
                  int _Options,
                  int _MaxRows,
                  int _MaxCols
                  &gt;
          inline void serialize(Archive &amp; arArchive,
                                Eigen::Matrix&lt;_Scalar,
                                _Rows,
                                _Cols,
                                _Options,
                                _MaxRows,
                                _MaxCols&gt; &amp; arMatrix,
                                const unsigned int aVersion)
          {
              boost::serialization::split_free(arArchive, arMatrix, aVersion);
          }
  
          template&lt;
                  class Archive,
                  typename _Scalar,
                  int _Rows,
                  int _Cols,
                  int _Options,
                  int _MaxRows,
                  int _MaxCols
                  &gt;
          inline void save(Archive &amp; arArchive,
                           const Eigen::Matrix&lt;_Scalar,
                           _Rows,
                           _Cols,
                           _Options,
                           _MaxRows,
                           _MaxCols&gt; &amp; arMatrix,
                           const unsigned int)
          {
              typedef typename Eigen::Matrix&lt;_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols&gt;::Index TEigenIndex;
  
              const TEigenIndex lRows = arMatrix.rows();
              const TEigenIndex lCols = arMatrix.cols();
  
              arArchive &lt;&lt; lRows;
              arArchive &lt;&lt; lCols;
  
              if(lRows &gt; 0 &amp;&amp; lCols &gt; 0)
              {
                  arArchive &amp; boost::serialization::make_array(arMatrix.data(), arMatrix.size());
              }
          }
  
          template&lt;
                  class Archive,
                  typename _Scalar,
                  int _Rows,
                  int _Cols,
                  int _Options,
                  int _MaxRows,
                  int _MaxCols
                  &gt;
          inline void load(Archive &amp; arArchive,
                           Eigen::Matrix&lt;_Scalar,
                           _Rows,
                           _Cols,
                           _Options,
                           _MaxRows,
                           _MaxCols&gt; &amp; arMatrix,
                           const unsigned int)
          {
              typedef typename Eigen::Matrix&lt;_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols&gt;::Index TEigenIndex;
  
              TEigenIndex lRows, lCols;
  
              // deserialize meta data
              arArchive &amp; lRows;
              arArchive &amp; lCols;
  
              // do some error handling here
  
              if(lRows &gt; 0 &amp;&amp; lCols &gt; 0)
              {
                  // deserialize data
                  arArchive &amp; 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&lt;class Archive&gt;
          void serialize(Archive &amp;ar, const unsigned int)
          {
              ar &amp; m;
          }
  };
  
  
  int main(void)
  {
      using namespace boost::archive;
  
      // Serialize
      TestClass TestA;
      std::ofstream oss("test.log");
      {
          text_oarchive oa(oss);
          oa &lt;&lt; TestA;
      }
  
      // deserialize now
      TestClass TestB;
      std::ifstream iss("test.log");
      {
          text_iarchive ia(iss);
          ia &gt;&gt; TestB;
      }
  }
  </code></pre>
  
  <p>[EDIT 2019-02-06]<br>
  GCC-Bug: <a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84075" rel="nofollow noreferrer">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84075</a> <br>
  Eigen-Bug: <a href="http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1676" rel="nofollow noreferrer">http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1676</a></p>
  
  <p>[EDIT 2019-02-07]<br>
  Boost PR: <a href="https://github.com/boostorg/serialization/pull/144" rel="nofollow noreferrer">https://github.com/boostorg/serialization/pull/144</a></p>