2
votes

Hell ! I'm trying to make a class that would help me with outputting text to stdout ... Anyway, everything is working, except for one thing. Let's say that I've create object of my class called out. When I do this, everything works prefectly:

out<<"test test"<<std::endl;

And it also works when I do this:

out<<QString("another string")<<std::endl;

But, when I try to chain these two thing together, like this:

out<<"test test"<<std::endl<<QString("another string")<<std::endl;

I get that super-big error, that's eventually telling me that operator<< doesn't accept parameter of type QString. That's strange, because it works OK when I don't chain QString ... Also this works:

out<<"test test"<<std::endl<<"another string"<<std::endl;

and this:

out<<QString("another string")<<std::endl<<"test test"<<std::endl;

So I guess I have problem with my operator<< function ... Either I didn't make operator<< correctly, or I don't return correct value. Or maybe something else is wrong. Anyway, I can't figure it out, so could you help me ? Bellow is source code:

output.h: http://xx77abs.pastebin.com/b9tVV0AV output.cpp: http://xx77abs.pastebin.com/5QwtZRXc

And of course, the super-big error :D

http://xx77abs.pastebin.com/8mAGWn47

EDIT: for all you wondering, I'm not using namespaces ...

3
Where are you testing these printouts from? output.cpp?Jeremiah Willcock

3 Answers

1
votes

Are you using namespaces? if you are, have you defined the operator<< for QString in a specific namespace? I can't see anything wrong with the above code (except the overload should accept a const reference rather than a copy!)

EDIT: should add, if it is in a namespace, move it out, else it will not be found.

EDIT2: add the declaration of the operator<< to the header file, after your class declaration - the compiler does not know of the existence of this overload until you do.

std::ostream& operator<<(std::ostream &out, const QString& var);
1
votes

This compiles for me (with the command line from your third link):

#include <iostream>
#include <sstream>
#include <QString>

class Output: public std::ostream
{
    friend std::ostream& operator<<(std::ostream &out, const QString var);
private:

    class StreamBuffer: public std::stringbuf
    {
    private:
        std::ostream &out;
        QString prefix;

    public:
        StreamBuffer(std::ostream& str, const QString &p);
         virtual int sync();
    };

    StreamBuffer buffer;

public:
    Output(const QString &prefix);
};
 Output::Output(const QString &prefix) :
    std::ostream(&buffer), buffer(std::cout, prefix)
{

}

Output::StreamBuffer::StreamBuffer(std::ostream& str, const QString &p)
    :out(str)
{
    prefix = p + "-> ";
}

std::ostream& operator<<(std::ostream &out, const QString var)
{
    out<<qPrintable(var);

    return out;
}

int Output::StreamBuffer::sync()
{
    out <<qPrintable(prefix)<< str();
    str("");
    out.flush();
    return 0;
}

int main()
  {
  Output out (QString (">")) ;
  out<<"test test"<<std::endl;
  out<<QString("another string")<<std::endl;
  out<<"test test"<<std::endl<<QString("another string")<<std::endl;
  }

If it compiles for you too, you should be able to morph it into your failing code to find the error.

1
votes

I feel compelled to note that Qt provides a function/class to do exactly this, and it's called QDebug. Since you're already bound to Qt, it should not be a problem to use it.