Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implicitly convert Qt objects to QString?

What's the best way of making all of the commented code below work in a standard C++/Qt way?

class A {
public:
    A() { }
    virtual ~A() { }
    virtual QString toString() { return "A"; }
};

class B: A {
public:
    B() { }
    ~B() { }
    QString toString() { return "B"; }
};

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    A a_;
    B b_;

    // qDebug() << a_;  // I can make this work by overloading << yes?
    // qDebug() << b_;

    // QString x = a_;  // How do I make this work?
    // QString y = b_;

    QString s = a_.toString(); // What I'm doing at present
    qDebug() << b_.toString(); // What I'm doing at present

    return a.exec();
}

I have a hierarchy of instances of my own Qt classes that all derive from the same base class. I'd like to turn them into strings implicitly in a standard way to be displayed in a Qt ui:

I can do it explicitly myself as above with my own standard method like toString above, but it's not implicit and I'd rather follow a Qt or C++ convention as I believe there is one I'm not aware of.

The strings will eventually be displayed in Q*View controls which I believe means overloading operator << won't be enough on it's own.

like image 360
Peter McG Avatar asked Dec 12 '22 16:12

Peter McG


1 Answers

You just add a so-called conversion function:

struct foo
{
    operator int() { return 5; }
};

foo f;
int i = f; // uses operator to convert to int

So in your case, just replace virtual QString toString() with virtual operator QString().


That said, implicit operators are generally frowned-upon. Not only are casts frowned upon, but now you're allowing a cast to happen implicitly. C++0x actually allows us to tack on explicit to the conversion functions to make sure we explicitly cast, but I don't know which compilers support that.

I think you'd be much better off leaving what you have, and just adding:

// I assume qDebug() is convertible to std::ostream
std::ostream& operator<<(std::ostream& stream, const A& val)
{
    stream << val.toString(); // would need to make function const, of course

    return stream;
}

And leaving the rest explicit.

like image 138
GManNickG Avatar answered Dec 28 '22 08:12

GManNickG