2016-11-22 73 views
1

我在嘗試從另一個使用該操作符的文件中重載運算符< <時出錯,並且不明白爲什麼。爲什麼我不能在另一個文件中重載<<運算符?

此代碼的工作

(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; 
} 

(生成文件)

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 

(的輸出./酒吧)

現在
a 

,如果我創建Foo.cpp中,和移動的std::ostream& operator<<(std::ostream& , Foo)的定義存在,並修改Makefile文件我這樣

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 

它不工作,我開始得到一噸的編譯器錯誤

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; 
      ^

和非常相似的其他錯誤。

爲什麼?

+0

你有沒有包括對不對?即foo.cpp中的#include ' –

回答

2

operator <<仍然是一個像任何其他(具有一些額外的屬性)的功能。它的聲明必須在所有想要使用它的文件中都可見。所以,如果你擺脫main.cpp其定義爲foo.cpp,你需要把一個聲明,它在foo.hpp

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

謝謝你這個明確的答案。 – mangenouilles

0

加入extern std :: ostream &運營商< <(std :: ostream &,Foo);在bar.cpp固定它,它的工作原理。