Search code examples
c++g++operator-overloadingnetbeans-8ostream

error: cannot bind ‘std::ostream in implementation file


First: I have tried reading and modifying my code based off no less than 7 other similar questions. At best, the other options trigger an avalanche of errors. With my current code, I'm down to a single error.

Putting it inside the class and using "friend" doesn't work, and using ostream& operator<< (ostream &out, const Fraction &rhs) makes a whole lot more errors. The frustrating thing is that in c9.io this code works, but not on Netbeans.

In my main.cpp:

#include <iostream>
#include "fraction.h"
using namespace std;
int main() {
    Fraction f(3, 4);
    cout << f;   
    return 0;
}

In fraction.h:

#ifndef FRACTION_H
#define FRACTION_H

class Fraction{
    public:
        //constructor defs            
        //accessors           
        //modifiers/mutators
        void setNumer(int newNum);
        void setDenom(int newDenom);
        void reduce();

    private:
        //instance variables
        int numer;
        int denom;
        //helper functions
        int gcd(int a, int b);
}; 
#endif /* FRACTION_H */

And in fraction.cpp:

#include "fraction.h"
#include <cmath>
#include <iostream>
using namespace std;

//code for constructors

//accessors
int Fraction::getNumer(){
    return numer;
}

int Fraction::getDenom(){
    return denom;
}

//modifiers/mutators

//other operator definitions

ostream& operator<< (ostream &out, Fraction &rhs){
    if(rhs.getNumer() == 0){
        out << 0;
    } else if(rhs.getNumer() == rhs.getDenom()){
        out << 1;
    } else {
        rhs.reduce();
        out << rhs.getNumer() << "/" << rhs.getDenom();
    }
}

The output is:

g++    -c -g -std=c++11 -MMD -MP -MF "build/Debug/GNU-Linux/main.o.d" -o build/Debug/GNU-Linux/main.o main.cpp
main.cpp: In function ‘int main()’:
main.cpp:6:13: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
     cout << f;   
             ^
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from main.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Fraction]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
     ^

Solution

  • There is no knowledge of the operator<< function that is defined in Fraction.cpp in main.cpp Hence, the line

    cout << f;
    

    is a problem.

    Add the declaration of the function in the .h file.

    #ifndef FRACTION_H
    #define FRACTION_H
    
    #include <iostream>
    
    class Fraction{
        public:
            //constructor defs            
            //accessors           
            //modifiers/mutators
            void setNumer(int newNum);
            void setDenom(int newDenom);
            void reduce();
    
        private:
            //instance variables
            int numer;
            int denom;
            //helper functions
            int gcd(int a, int b);
    }; 
    
    std::ostream& operator<< (std::ostream &out, Fraction const& rhs);
    //                                                    ^^^^ Using const&, not just Fraction&
    
    #endif /* FRACTION