mangenouilles mangenouilles - 11 days ago 5
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

(foo.hpp)

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


(bar.cpp)

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

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

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


(Makefile)

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


(output of ./bar)

a


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

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


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 ?

Answer

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);
Comments