title: C++ compiler doesn't consider friend class declaration
body: <p>I'm trying to rewrite the program shown in the textbook (C++ Primer). This is small email-like program that contains two main <code>Message</code> and <code>Folder</code> classes. Source files are as below:</p>
  <p><strong>Folder.h</strong></p>
  <pre><code>#pragma once
  
  #include &lt;set&gt;
  #include &lt;string&gt;
  
  #include &quot;Message.h&quot;
  
  using std::string;
  using std::set;
  
  
  class Folder {
      friend class Message;
      friend void swap(Folder&amp;, Folder&amp;);
  
  public:
      Folder(const string &amp;fname):
          name(fname) { }
      Folder(const Folder&amp;);
      Folder&amp; operator=(const Folder&amp;);
      ~Folder();
  
      void print_debug();
  
  private:
      string name;
      set&lt;Message*&gt; msgs;
  
      void add_to_Message(const Folder&amp;);
      void remove_from_Message();
  
      void addMsg(Message*);
      void remMsg(Message*);
  };
  </code></pre>
  <p><strong>Message.h</strong></p>
  <pre><code>#pragma once
  
  #include &lt;string&gt;
  #include &lt;set&gt;
  
  using std::set;
  using std::string;
  
  class Folder;
  
  class Message {
      friend class Folder;
      friend void swap(Message&amp;, Message&amp;);
  
  public:
      // folders is implicitly initialized to the empty set
      explicit Message(const string &amp;str = &quot;&quot;):
          contents(str) { }
      // copy control to manage pointers to this Message
      Message(const Message&amp;);
      Message&amp; operator=(const Message&amp;);
      ~Message();
      // add/remove this Message from the specified Folder's set of messages
      void save(Folder&amp;);
      void remove(Folder&amp;);
  
      void print_debug();
  private:
  
      string contents;
      set&lt;Folder*&gt; folders;
  
      void add_to_Folders(const Message&amp;);
      void remove_from_Folders();
  
      void addFldr(Folder*);
      void remFldr(Folder*);
  
  };
  </code></pre>
  <p><strong>Folder.cc</strong></p>
  <pre><code>#include &lt;iostream&gt;
  
  #include &quot;Message.h&quot;
  #include &quot;Folder.h&quot;
  
  void swap(Folder &amp;lhs, Folder &amp;rhs) {
      using std::swap;
  
      lhs.remove_from_Message();
      rhs.remove_from_Message();
  
      swap(lhs.msgs, rhs.msgs);
      swap(lhs.name, rhs.name);
  
      lhs.add_to_Message(lhs);
      rhs.add_to_Message(rhs);
  }
  
  Folder::Folder(const Folder &amp;f):
      msgs(f.msgs)
  {
      add_to_Message(f);
  }
  
  Folder::~Folder() {
      remove_from_Message();
  }
  
  Folder&amp; Folder::operator=(const Folder &amp;rhs) {
      remove_from_Message();
      msgs = rhs.msgs;
      name = rhs.name;
      add_to_Message(rhs);
  
      return *this;
  }
  
  void Folder::addMsg(Message *msg) {
      msgs.insert(msg);
  }
  
  void Folder::remMsg(Message *msg) {
      msgs.erase(msg);
  }
  
  void Folder::add_to_Message(const Folder &amp;f) {
      for (auto m : msgs)
          m-&gt;addFldr(this);
  }
  
  void Folder::remove_from_Message() {
      for (auto m : msgs)
          m-&gt;remFldr(this);
  }
  
  void Folder::print_debug() {
      std::cout &lt;&lt; &quot;Folder name : &quot; &lt;&lt; name &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;Messages : &quot;;
      for (const auto msg : msgs)
          std::cout &lt;&lt; msg-&gt;contents &lt;&lt; &quot; &quot;;
      std::cout &lt;&lt; std::endl;
  }
  </code></pre>
  <p><strong>Message.cc</strong></p>
  <pre><code>#include &lt;iostream&gt;
  
  #include &quot;Message.h&quot;
  #include &quot;Folder.h&quot;
  
  Message::Message(const Message &amp;msg):
      contents(msg.contents), folders(msg.folders)
  {
      add_to_Folders(msg);
  }
  
  Message&amp; Message::operator=(const Message &amp;rhs) {
      remove_from_Folders();
      contents = rhs.contents;
      folders = rhs.folders;
      add_to_Folders(rhs);
  
      return *this;
  }
  
  Message::~Message() {
      remove_from_Folders();
  }
  
  void Message::save(Folder &amp;f) {
      folders.insert(&amp;f);
      f.addMsg(this);
  }
  
  void Message::remove(Folder &amp;f) {
      folders.erase(&amp;f);
      f.remMsg(this);
  }
  
  void Message::add_to_Folders(const Message &amp;msg) {
      for (auto f : msg.folders)
          f-&gt;addMsg(this);
  }
  
  void Message::remove_from_Folders() {
      for (auto f: folders)
          f-&gt;remMsg(this);
  }
  
  void swap(Message &amp;lhs, Message &amp;rhs) {
      using std::swap;
  
      for (auto f: lhs.folders)
          f-&gt;remMsg(&amp;lhs);
      for (auto f : rhs.folders)
          f-&gt;remMsg(&amp;rhs);
  
      swap(lhs.folders, rhs.folders);
      swap(lhs.contents, rhs.contents);
  
      for (auto f : lhs.folders)
          f-&gt;addMsg(&amp;lhs);
      for (auto f : rhs.folders)
          f-&gt;addMsg(&amp;rhs);
  }
  
  void Message::addFldr(Folder *f) {
      folders.insert(f);
  }
  
  void Message::remFldr(Folder *f) {
      folders.erase(f);
  }
  
  void Message::print_debug() {
      std::cout &lt;&lt; &quot;Message content : &quot; &lt;&lt; contents &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;Exists in folders : &quot;;
      for (const auto f : folders)
          std::cout &lt;&lt; f-&gt;name &lt;&lt; &quot; &quot;;
      std::cout &lt;&lt; std::endl;
  }
  </code></pre>
  <p><strong>main.cc</strong></p>
  <pre><code>#include &quot;Message.h&quot;
  #include &quot;Folder.h&quot;
  
  int main() {
      Folder f1(&quot;folder1&quot;);
      Folder f2(&quot;folder2&quot;);
      Message msg1(&quot;msg 1&quot;);
      Message msg2(&quot;msg 2&quot;);
      Message msg3(&quot;msg 3&quot;);
  
      msg1.save(f1);
      msg2.save(f1);
      msg2.save(f2);
      msg3.save(f2);
  
      f1.print_debug();
      f2.print_debug();
      msg1.print_debug();
      msg2.print_debug();
      msg3.print_debug();
  
      return 0;
  }
  </code></pre>
  <p>When I try to compile these source files with command:</p>
  <pre><code>g++ main.cc Message.cc Folder.cc
  </code></pre>
  <p>It gives error:</p>
  <pre><code>Message.cc: In function ‘void swap(Message&amp;, Message&amp;)’:
  Message.cc:49:23: error: ‘void Folder::remMsg(Message*)’ is private within this context
     49 |         f-&gt;remMsg(&amp;lhs);
        |                       ^
  In file included from Message.cc:4:
  Folder.h:33:10: note: declared private here
     33 |     void remMsg(Message*);
        |          ^~~~~~
  Message.cc:51:23: error: ‘void Folder::remMsg(Message*)’ is private within this context
     51 |         f-&gt;remMsg(&amp;rhs);
        |                       ^
  In file included from Message.cc:4:
  Folder.h:33:10: note: declared private here
     33 |     void remMsg(Message*);
        |          ^~~~~~
  Message.cc:57:23: error: ‘void Folder::addMsg(Message*)’ is private within this context
     57 |         f-&gt;addMsg(&amp;lhs);
        |                       ^
  In file included from Message.cc:4:
  Folder.h:32:10: note: declared private here
     32 |     void addMsg(Message*);
        |          ^~~~~~
  Message.cc:59:23: error: ‘void Folder::addMsg(Message*)’ is private within this context
     59 |         f-&gt;addMsg(&amp;rhs);
        |                       ^
  In file included from Message.cc:4:
  Folder.h:32:10: note: declared private here
     32 |     void addMsg(Message*);
        |          ^~~~~~
  </code></pre>
  <p>Why complains about private methods while <code>Folder</code> and <code>Message</code> classes are friends?</p>