2

I'm trying to overload operator<<, and it drove me crazy:

std::ostream& operator<<(std::ostream & lhs, TuringMachine::TRTable& rhs){

    for(auto& statePtr : rhs){

        lhs << statePtr.first->getLabel().toStdString();
        for(auto& charPtr: statePtr.second){

            //lhs << '\t';
            lhs << charPtr.first.toAscii() ;
            //lhs << 'b ';
            lhs << charPtr.second.getState().getLabel().toStdString() << std::endl;
        }
    }

return lhs;
}

TRTable is a typedeffor std::map<State*, std::multimap<QChar, Transition>>. Statehas its label as a QString hence the call to .toStdString().

In another class I call std::cout << machine->table << std::endl; with machine beeing a TuringMachine* and this gives me

error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'

What am I doing wrong? Why &&?

EDIT: using g++ 4.6 and -std=c++0x

TeaOverflow
  • 2,468
  • 3
  • 28
  • 40
  • What types do toStdString and toAscii return? Do you know which line the error message is for? – Scott Langham May 26 '12 at 13:27
  • `toStdString()` and `toAscii()` are member fuctions of `QString` and `QChar`. They return a `std::string` and a `char`, respectively. The error occurs in the line where I call `std::cout << machine->table << std::endl` – TeaOverflow May 26 '12 at 14:20
  • 3
    Is a declaration of this `operator<<` function visible from the point where you try to use it? (Earlier in the same file, or in an #included header) – aschepler May 26 '12 at 14:42
  • 1
    It sounds like you changed some things. Let's sync up with a [SSCCE](http://sscce.org). – Potatoswatter May 26 '12 at 15:44
  • 1
    From the answers here: http://stackoverflow.com/questions/10651161/overlading-operator-cannot-bind-lvalue-to-stdbasic-ostreamchar It sounds similar. The compiler may not be considering your operator for some reason. That makes aschepler's suggestion sound very good! – Scott Langham May 26 '12 at 15:46
  • @aschepler When putting it in a header, I was getting "multiple definitions" errors. The I read about making it `inline` and now it works! Thanks you! But why didn't the guards of the header file suffice? – TeaOverflow May 26 '12 at 16:47

3 Answers3

2

In which namespace did you declare the operator<<? Since TRTable is a typedef ADL does not apply, so the operator<< is searched only in namespace std by ADL, since this is where the actual class is defined. So you might have to use the namespace where you defined the operator<< when you want to use it.

Florian Sowade
  • 1,727
  • 12
  • 20
  • To my shame I must admit that I simply put it in the .cpp file. I was trying to avoid the multiple difinitions error and was plain unaware of the fact that I could do so by leaving it in the header and prefixing it with `inline` and everything's gonna be fine. Just as it is now :-) – TeaOverflow May 26 '12 at 17:37
0

lhs should have type std::ostream &. No const.

chys
  • 1,546
  • 13
  • 17
0

rhs should be const TuringMachine::TRTable&:

std::ostream& operator<<(std::ostream& lhs, const TuringMachine::TRTable& rhs)