why I cannot overload the << operator in another file?
<p>I am getting an error when trying to overload the &lt;&lt; operator from another file where I use the operator and do not understand why. </p>

<p>This code works </p>

<p>(foo.hpp) </p>

<pre><code>#ifndef FOO_HPP
#define FOO_HPP
enum class Foo { a, b };
#endif
</code></pre>

<p>(bar.cpp) </p>

<pre><code>#include "foo.hpp"
#include &lt;iostream&gt;

std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, Foo x) {
  switch(x) {
  case Foo::a :
    out &lt;&lt; "a";
    break;
  case Foo::b :
    out &lt;&lt; "b";
    break;
  }
  return out;
}

int main(int argc, char ** argv) {
  Foo x {Foo::a};
  std::cout &lt;&lt; x &lt;&lt; std::endl;
  return 0;
}
</code></pre>

<p>(Makefile)</p>

<pre><code>CC=g++
CFLAGS=--std=c++11 -Wall

bar : bar.o 
    $(CC) $(CFLAGS) bar.o -o bar

bar.o : bar.cpp foo.hpp
    $(CC) $(CFLAGS) -c bar.cpp foo.hpp
</code></pre>

<p>(output of ./bar)</p>

<pre><code>a
</code></pre>

<p>Now, if I create foo.cpp, and move the definition of <code>std::ostream&amp; operator&lt;&lt;(std::ostream&amp; , Foo)</code> there, and modify my Makefile this way</p>

<pre><code>CC=g++
CFLAGS=--std=c++11 -Wall

bar : bar.o foo.o
    $(CC) $(CFLAGS) bar.o foo.o -o bar

foo.o : foo.cpp foo.hpp
    $(CC) $(CFLAGS) -c foo.cpp foo.hpp

bar.o : bar.cpp foo.hpp
    $(CC) $(CFLAGS) -c bar.cpp foo.hpp
</code></pre>

<p>It does not work and I get a ton of compiler errors starting with</p>

<pre><code>bar.cpp: In function ‘int main(int, char**)’:
bar.cpp:6:13: error: no match for ‘operator&lt;&lt;’ (operand types are ‘std::ostream {aka std::basic_ostream&lt;char&gt;}’ and ‘Foo’)
   std::cout &lt;&lt; x &lt;&lt; std::endl;
             ^
</code></pre>

<p>and very similar other errors.</p>

<p>Why ? </p>