mangenouilles mangenouilles - 5 months ago 29
C++ Question

why I cannot overload the << operator in another file?

I am getting an error when trying to overload the << operator from another file where I use the operator and do not understand why.

This code works


#ifndef FOO_HPP
#define FOO_HPP
enum class Foo { a, b };


#include "foo.hpp"
#include <iostream>

std::ostream& operator<<(std::ostream& out, Foo x) {
switch(x) {
case Foo::a :
out << "a";
case Foo::b :
out << "b";
return out;

int main(int argc, char ** argv) {
Foo x {Foo::a};
std::cout << x << std::endl;
return 0;


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

(output of ./bar)


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

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

It does not work and I get a ton of compiler errors starting with

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

and very similar other errors.

Why ?


operator << is still a function like any other (with some additional properties). Its declaration must be visible in all files which want to use it. So if you move its definition from main.cpp into foo.cpp, you will need to put a declaration for it in foo.hpp:

std::ostream& operator<<(std::ostream& out, Foo x);