title: error: no match for 'operator<<' using boost::serialisation
body: <p>I am trying to get some (hitherto) windows code to compile on a unix machine but am getting some errors at the following method:</p>
  
  <pre><code>namespace EDIN {
      void World::Save(char const filename[])                                                  
      {                                                                                        
          std::ofstream ofs(filename);                                                         
  
          boost::archive::text_oarchive oa(ofs);                                               
  
          oa &lt;&lt; this &lt;&lt; cellSequence &lt;&lt; report; // line 590: error!
      }
  }
  </code></pre>
  
  <p>The error looks like this:</p>
  
  <blockquote>
    <p>test.cpp: In member function ‘void EDIN::World::Save(const char*)’:
    test.cpp:122:12: error: no match for ‘operator&lt;&lt;’ (operand types are
    ‘boost::archive::text_oarchive’ and ‘EDIN::World*’)
             oa &lt;&lt; this &lt;&lt; cellSequence &lt;&lt; report; // line 590: error!
                ^ test.cpp:122:12: note: candidate is: In file included from
    /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/common_oarchive.hpp:22:0,
                     from /home/armanschwarz/lib/boost_1_55_0/boost/archive/basic_text_oarchive.hpp:32,
                     from /home/armanschwarz/lib/boost_1_55_0/boost/archive/text_oarchive.hpp:31,
                     from test.cpp:1: /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/interface_oarchive.hpp:62:15:
    note: Archive&amp;
    boost::archive::detail::interface_oarchive::operator&lt;&lt;(T&amp;)
    [with T = EDIN::World*; Archive = boost::archive::text_oarchive]
         Archive &amp; operator&lt;&lt;(T &amp; t){
                   ^ /home/armanschwarz/lib/boost_1_55_0/boost/archive/detail/interface_oarchive.hpp:62:15:
    note:   no known conversion for argument 1 from ‘EDIN::World*’ to
    ‘EDIN::World*&amp;’</p>
  </blockquote>
  
  <p>I'm using boost 1.55.0 (same as when I used to compile this on Visual Studio). Can anyone spot what I'm doing wrong here?</p>
  
  <p>Here is a self-contained example from sehe:</p>
  
  <pre><code>#include &lt;boost/archive/text_oarchive.hpp&gt;
  #include &lt;boost/archive/text_iarchive.hpp&gt;
  #include &lt;boost/serialization/serialization.hpp&gt;
  #include &lt;boost/serialization/vector.hpp&gt;
  #include &lt;boost/serialization/string.hpp&gt;
  #include &lt;boost/serialization/valarray.hpp&gt;
  #include &lt;chrono&gt;
  
  namespace EDIN
  {
      struct Region
      {
          int id;
          Region(int id = 42) : id(id) {}
  
        private:
          friend class boost::serialization::access;
          template&lt;class Archive&gt; void serialize(Archive &amp; ar, const unsigned int file_version)
          {
              ar &amp; id;
          }
      };
  
      struct Scheme
      {
          std::string GetSchemeType() const { return "scheme_type_42"; }
      };
  
  
      class World
      {
          // dummy members to make it compile
          // will be different things of course
          int mass, epoch;
          std::chrono::system_clock::time_point _start;
  
          std::string report;
        public:
          std::vector&lt;int&gt; cellSequence; // for demo, public
  
          World(std::string&amp;, EDIN::Region&amp;, unsigned int&amp;, const std::chrono::system_clock::time_point&amp;)
              : mass(99), epoch(88), _start(std::chrono::system_clock::now()), report("Report101")
          {
              // TODO!
          }
  
          Region       Bounds() const { return Region();       }
          int          Epoch()  const { return epoch;          }
          EDIN::Scheme Scheme() const { return EDIN::Scheme(); }
          std::chrono::system_clock::time_point StartingWallTime() const {
              return _start;
          }
  
          World()
              : mass(99), epoch(88), _start(std::chrono::system_clock::now()), report("Report101")
          {
          }
  
          void Save(char const filename[]);
          static World* Load(char const filename[]);
  
          private:
              friend class boost::serialization::access;
              template&lt;class Archive&gt; void serialize(Archive &amp; ar, const unsigned int file_version)
              {
                  ar &amp; mass &amp; epoch;
              }
      };
  }
  
  namespace boost
  {
      namespace serialization
      {
          template&lt;class Archive&gt;
          inline void save_construct_data(Archive &amp; ar, EDIN::World const * t, unsigned const int file_version)
          {
              time_t const totalRunningTime = std::chrono::duration_cast&lt;std::chrono::duration&lt;time_t, std::milli&gt;&gt;(
                  std::chrono::system_clock::now() - t-&gt;StartingWallTime()).count();
  
              EDIN::Region const bounds = t-&gt;Bounds();
              time_t const epoch = t-&gt;Epoch();
  
              std::string tmp = t-&gt;Scheme().GetSchemeType();
              ar
                  &lt;&lt; bounds
                  &lt;&lt; epoch
                  &lt;&lt; totalRunningTime 
                  &lt;&lt; tmp;
          }
  
          template&lt;class Archive&gt;
          inline void load_construct_data(Archive &amp; ar, EDIN::World * t, const unsigned int file_version)
          {
              EDIN::Region bounds;
              unsigned epoch;
              time_t totalRunningTime;
              std::string schemeType;
              ar &gt;&gt;
                  bounds &gt;&gt;
                  epoch &gt;&gt;
                  totalRunningTime &gt;&gt;
                  schemeType;
  
              std::chrono::system_clock::time_point const startingWallTime =
                  std::chrono::system_clock::now() - std::chrono::duration&lt;time_t, std::milli&gt;(totalRunningTime);
  
              ::new(t) EDIN::World(schemeType,bounds,epoch,startingWallTime);
          }
      }
  }
  
  #include &lt;fstream&gt;
  
  namespace EDIN {
      void World::Save(char const filename[])
      {
          std::ofstream ofs(filename);
  
          boost::archive::text_oarchive oa(ofs);
  
          oa &lt;&lt; this &lt;&lt; cellSequence &lt;&lt; report; // line 590: error!
      }
  
      World* World::Load(char const filename[])
      {
          World *world = 0;
  
          std::ifstream ifs("world.save");
          boost::archive::text_iarchive ia(ifs);
  
          ia &gt;&gt; world;
          ia &gt;&gt; world-&gt;cellSequence &gt;&gt; world-&gt;report;
  
          return world;
      }
  }
  
  int main()
  {
      EDIN::World world;
      world.cellSequence.push_back(12345);
      world.cellSequence.push_back(-6767);
      world.Save("world.save");
  
      EDIN::World* restored = EDIN::World::Load("world.save");
      restored-&gt;Save("world2.save");
  
      delete restored;
  }
  </code></pre>
  
  <p>It <a href="http://coliru.stacked-crooked.com/a/859b52aea8810def" rel="nofollow">compiles fine here</a> using GCC 4.8.1 and Boost 1.55.0. I am using GCC 4.9.0 and boost 1.55.0.</p>
  
  <p><strong>EDIT: I have found a hack that seems to work:</strong></p>
  
  <p>The problem seems to be that G++ 4.9 doesn't want to cast <code>World::this</code> from <code>World*</code> to <code>World*&amp;</code>. Replacing the <code>World::Save</code> method with the following resolves the problem:</p>
  
  <pre><code>void World::Save(char const filename[])
  {
      std::ofstream ofs(filename);
  
      boost::archive::text_oarchive oa(ofs);
  
      World* thisCopy = this;
      oa &lt;&lt; thisCopy &lt;&lt; cellSequence &lt;&lt; report;
  }
  </code></pre>
  
  <p>There seems to be a difference in behaviour between GCC 4.8.1 and GCC 4.9 that causes the latter not to compile unless I create copy of the <code>this</code> pointer. If someone could point out why this is happening and whether or not it's a bug or intended change in behaviour that would be appreciated!</p>