为什么我不能重载<<运算符在另一个文件?

时间:2016-11-22 13:04:02

标签: c++

我在尝试重载<<时遇到错误从我使用运算符的另一个文件中的运算符,不明白为什么。

此代码有效

(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

(./bar的输出)

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

和非常相似的其他错误。

为什么?

2 个答案:

答案 0 :(得分:2)

operator <<仍然是一个像其他任何函数一样的函数(带有一些额外的属性)。它的声明必须在所有想要使用它的文件中可见。因此,如果您将其定义从main.cpp移至foo.cpp,则需要在foo.hpp中为其声明:

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

答案 1 :(得分:0)

添加extern std :: ostream&amp;运营商LT;≤(标准:: ostream的&安培;,富);在bar.cpp修复它并且它可以工作。