Can't overload << for Enum in C++

11,070

Solution 1

Multiple definition linker errors because you've defined the function in a header file that's included in two or more compilation units.

Either add inline, like

inline std::ostream& operator<<(std::ostream & os, Categoria & cat)

or move the definition to an implementation file (you still need a declaration in the header file then).

EDIT: PS: also, as others have mentioned (I didn't see that), pass the second argument by reference to const, like Categoria const& cat. Or if Categoriais an enum, pass it by value.

EDIT 2: PPS: if you move the definition to an implementation file, then to reduce needless dependencies for client code, move also the #include <iostream> to the implementation file, and in the header file then #include <iosfwd>.

Solution 2

Look at your function:

std::ostream& operator<<(std::ostream & os, Categoria & cat) 

It can only match a writable enumeration variable... make the type Categoria or const Categoria&.

Solution 3

Try like this:

std::ostream &operator<<( std::ostream &os, const Categoria obj );

EDIT

doh multiple definition. If you prefer to define a function in a header, then at least put inline :

inline
std::ostream &operator<<( std::ostream &os, const Categoria cat )
{
  switch (cat) {
  case LongoCurso:
      os << "Longo Curso";
      break;
  case MedioCurso:
      os << "Medio Curso";
      break;
  case Domestico:
      os << "Domestico";
  }
  return os;
}
Share:
11,070
F. P.
Author by

F. P.

\ /\ ) ( ') ( / ) \(__)|

Updated on June 04, 2022

Comments

  • F. P.
    F. P. almost 2 years

    I have created an enumerated data type to define possible flight lengths. I'd like to overload its << operator so the representation is nicer.

    When I compile this, I get the following error (posted for completeness' sake. Basically multiple definitions of operator <<(ostream&, Categoria&)):

    g++ -oProjectoAEDA.exe src\voo.o src\tui.o src\tripulante.o src\tipoaviao.o src\manga.o src\main.o src\datahora.o src\companhiaaerea.o src\aviao.o src\aeroporto.o
    src\tripulante.o: In function `ZlsRSoR9Categoria':
    c:/mingw/bin/../lib/gcc/i686-pc-mingw32/4.5.1/../../../../include/c++/4.5.1/new:103: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    src\tipoaviao.o: In function `ZlsRSoR9Categoria':
    c:/mingw/bin/../lib/gcc/i686-pc-mingw32/4.5.1/../../../../include/c++/4.5.1/new:103: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    src\manga.o: In function `ZlsRSoR9Categoria':
    c:/mingw/bin/../lib/gcc/i686-pc-mingw32/4.5.1/../../../../include/c++/4.5.1/new:103: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    src\main.o: In function `ZlsRSoR9Categoria':
    C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    src\companhiaaerea.o: In function `ZlsRSoR9Categoria':
    c:/mingw/bin/../lib/gcc/i686-pc-mingw32/4.5.1/../../../../include/c++/4.5.1/new:103: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    src\aviao.o: In function `ZlsRSoR9Categoria':
    c:/mingw/bin/../lib/gcc/i686-pc-mingw32/4.5.1/../../../../include/c++/4.5.1/new:103: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    src\aeroporto.o: In function `ZlsRSoR9Categoria':
    c:/mingw/bin/../lib/gcc/i686-pc-mingw32/4.5.1/../../../../include/c++/4.5.1/new:103: multiple definition of `operator<<(std::ostream&, Categoria&)'
    src\voo.o:C:\Users\Francisco\workspace_aeda\ProjectoAEDA\Debug/../src//headers/categoria.h:20: first defined here
    collect2: ld returned 1 exit status
    Build error occurred, build is stopped
    Time consumed: 928  ms.  
    

    This is the data file where both the enum is declared and the operator overloaded.

    /*
     * categoria.h
     *
     *  Created on: 9 de Out de 2010
     *      Author: Francisco
     */
    
    #ifndef CATEGORIA_H_
    #define CATEGORIA_H_
    
    #include <iostream>
    
    enum Categoria {
        LongoCurso,
        MedioCurso,
        Domestico
    };
    
    std::ostream& operator<<(std::ostream & os, Categoria & cat)
    {
      switch (cat) {
      case LongoCurso:
          os << "Longo Curso";
          break;
      case MedioCurso:
          os << "Medio Curso";
          break;
      case Domestico:
          os << "Domestico";
      }
      return os;
    }
    
    
    
    #endif /* CATEGORIA_H_ */
    

    EDIT: I tried const reference, const by value and non const value. None compiled.

  • sbi
    sbi over 13 years
  • F. P.
    F. P. over 13 years
    Thank you, that worked, but I moved the implementation to a source file.
  • Eamon Nerbonne
    Eamon Nerbonne over 13 years
    "darn, I can't see that here while editing": while editing there's a grey bar under the question title which you can drag down to reveal as much of the question text as necessary.
  • Tony Delroy
    Tony Delroy over 13 years
    I should have looked more carefully at your compiler errors... sorry! Kudos to Alf.
  • Trebor Rude
    Trebor Rude about 10 years
    @Cheersandhth "anum" should be "enum" in this answer. I don't have enough rep to make an edit that small.