C++0x in Qt

Published Thursday May 26th, 2011 | by

While many are so enthusiastic about QML and javascript technology, a few of us still code in C++ ;-) . C++ is about to get an upgrade: C++11 (formely known as C++0x). The final draft was aproved last march in the C++ standard commitee, and the final specification is expected to be published this summer. If you don’t know it yet, I invite you to read specialized pages, such as Wikipedia or C++0x FAQ

One of the goals of C++0x is supposed to make the language easier. Which is hardly possible since it only adds more stuff to learn, but with the hope that the “mosty used” subset of C++ should be easier and more intuitive.

The good news is that you do not need to wait to use it. You can start today. The compiler you use probably already supports some of C++0x: GCC or MSVC 2010

While you can already use C++0x with older Qt version such as Qt 4.7, Qt 4.8 will come with more support for some of the new C++0x constructs:

New Macros

Some macros are defined if the compiler supports the new features

Q_COMPILER_RVALUE_REFS
Q_COMPILER_DECLTYPE
Q_COMPILER_VARIADIC_TEMPLATES
Q_COMPILER_AUTO_TYPE
Q_COMPILER_EXTERN_TEMPLATES
Q_COMPILER_DEFAULT_DELETE_MEMBERS
Q_COMPILER_CLASS_ENUM
Q_COMPILER_INITIALIZER_LISTS
Q_COMPILER_LAMBDA
Q_COMPILER_UNICODE_STRINGS

Initializer lists
Qt 4.8 adds new constructors to QVector, QList, and QStringList which enable you to initialize them using the bracket initializer.
You can now do

QVector<int> testsData { 1, 2, 10, 42, 50, 123  };
QStringList options = { QLatin1String("foo"), QLatin1String("bar")  };

which initializes the containers with those element.

Rvalues references and move semantics

Most of Qt classes are implicitly shared, meaning it is efficient to copy them if you do not modify them (copy on write). This is not the case for std::vector, where each copy implies copying all the data.
So if you have code like

std::vector<int> m_foo;
...
m_foo = getVector();

The getVector may construct a new std::vector, and return it as a temporary object, then the std::vector::operator= will delete the old content of m_foo, then copy all the data from the temporary vector to m_foo. At the end of the statement, the temporary vector will be destroyed, and its destructor will delete its data. It would be way more efficient if instead, the operator= would exchange m_foo data with the temporary vector’s data. That way, m_foo’s old data would be deleted when the temporary is destroyed, and we would not create a useless copy. This is what the move semantics in C++0x is, and it is achieved through rvalue references.

Even if copying an implicitly shared class is cheap, it does not come for free, we still have to increase and decrease the reference count, and the calls to the operator= cannot be inlined, since it accesses the private data. (We can’t inline that to ease binary compatibility).
So now, look at the Qt 4.8′s QImage move operator:

#ifdef Q_COMPILER_RVALUE_REFS
    inline QImage &operator=(QImage &&other)
    { qSwap(d, other.d); return *this; }
#endif

We just swap the internal data of the two images, this is a very cheap operation compared to the normal operation which requires a function call. We added this to most of the implicitly shared classes in Qt.
Since the operator= of all our containers is used a lot with temporaries, it may give small improvements to the speed of Qt, which might be a reason to compile Qt with C++0x support (see below).

Range-based for-loop

Qt had already a very convenient foreach, You can also find it in some other library, such as Boost.
The Qt foreach works with complicated macro, But C++0x goes further and make this construct part of the language.
So, instead of writing

foreach(const QString &option, optionList) { ... }

you can write

for (const QString &option : optionList) { ... }

There is a slight difference between the two: Qt does a copy of the container before iterating.
This is cheap for Qt container as they use implicit sharing, but is expensive with standard containers that do a deep copy of the whole content.
The C++0x range-based for does not copy, which means the behaviour is undefined if you add or remove items from the container as you iterate.
The new for will call the begin() and end() functions which are going to make a copy of the Qt container if it is shared and non const. Hence, it is better to pass const containers.

template<class T> const T &const_(const T &t) { return t; }
for(auto it : const_(vector)) { ... }

Lambda

We tested lambda with some of the QtConcurrent functions.
We tested it with QtConcurrent::run and QtConcurrent::map
But it does not work yet for QtConcurrent::mapped, we may fix that in the future.

So the scale example of the Qtconcurrent::map documentation could be rewriten like that

  QList<QImage> images = ...
  QFuture<void> future = QtConcurrent::map(images, [](QImage &image) {
            image = image.scaled(100,100);
        });

I am also researching using lambda in signal/slots connections, but that would be for Qt5.

Unicode Strings

We do not yet support the new string types. But that might come later.

Go and use it!

If you are using MSVC 2010, there is nothing to do, you can already use some feature such as the lambdas or the rvalue references.

If you are using gcc, you need to pass the flag -std=c++0x.
You can do that in your qmake project file like this:

QMAKE_CXXFLAGS += -std=c++0x

If you want to compile Qt using C++0x you can do

CXXFLAGS="-std=c++0x" ./configure

Qt compiled with C++0x is binary compatible with the good old C++. And you do not need to compile Qt with C++0x to write your own application using C++0x,

Did you like this? Share it:
Bookmark and Share

Posted in C++, KDE, News, Qt

30 comments to C++0x in Qt

Ian Ross says:

So, there is nothing special required to compile Qt in VS 2010? Nothing like settings the CXX_FLAGS for GCC?

Thanks a lot – this looks promising.

What about C++11 “auto” keyword support in Qt Creator intellisence? Right now, Qt Creator will not treat identifiers declared with “auto” as corresponding rvalue – so no intellisence will trigger on “.” or “->”.

Fazer says:

Will official Qt binaries be compiled with C++11 in the future?

Kai Köhne says:

@Grigory: Actually Qt Creator already supports lots of the 0x language extensions. For auto, feel free to vote on http://bugreports.qt.nokia.com/browse/QTCREATORBUG-4654 :)

codenode says:

Wow! This is awesome news :)
In my Opinion QML is only valid for UI, so C++ 2011 Support is really great!

What about the toolchain for symbian, will it support this?
Also I’d like to ask, if something like enable_if could find support, as you can do cool stuff with it like this in C++0x:
http://codepaste.net/23yo8o

Also Scott Meyer has a great Site about C++0x support of different compilers:
http://www.aristeia.com/C++0x/C++0xFeatureAvailability.htm

Stephen Chu says:

Last time I tried c++0x on OS X, it didn’t work. GCC on Mac is so behind…

Will Qt also in the future use the C++11 threading support and how much will it benefit from that?

Strayer says:

# I am also researching using lambda in signal/slots connections, but that would be for Qt5.

Dear god, yes please.

J. Puhr says:

Some very, very good video introductions to the C++0x core concepts are available from Microsoft:

http://channel9.msdn.com/Tags/stephan-t-lavavej

Paolo Bonzini says:

Are you missing an underscore for const_ in the last example for “Range-based for-loop”?

Olivier Goffart says:

@Ian: That is correct

@Fazer: I don’t know. But as it is binary compatible, it does not really matter that much.

@codenode: Thanks for the links. I do not know about the symbian toolchain, but I don’t think so.
Regarding enable_if, it is part of the stl in C++0x (you have std::enable if), or you can use boost. It is not the goal of Qt to provide that kind of feature, so we have no plans to expose it in the Qt public API.

@Stephen Chu: Hopefully, clang will catch up…

@Toni Nikkanen: No, we are not going to use C++11 threading support in the short term

@Paolo Bonzini: It is there. You may be the victime of a rendering bug.

Eckhart Köppen says:

@Fazer: yes, we’re planning to support VS2010 as one of the default compilers.

Sekar says:

Very informative post.

I have to say C++0x is an abomination of a language. The ransom use of curly brace in initializer lists is quite horrible. And this one:

QFuture future = QtConcurrent::map(images, [](QImage &image) {
image = image.scaled(100,100);
});

Hendrik says:

Great news!

@Stephen Chu: Apple drops the GCC-support as they are using clang. Clang already supports some c++0x features and is catching up very fast.

Achilleas Margaritis says:

Will the signals/slots mechanism use real functions?

One of the greatest problems of Qt, the one that has got me thinking to switch to wxWidgets, is the signals/slots mechanism: it requires objects to inherit from QObject, and use the MOC, which makes it very frustrating to setup c++ projects with tools Qt does not support.

I think that using the MOC should have been optional.

const says:

why not write a macro which called ‘constfor’…^_^

Jason says:

This is nice, thanks! I think that getting signals/slots working with lambdas should be one of the highest priority c++11-related items.

Alex says:

@Achilleas Margaritis:

And how do you get object introspection? The ability to enumerate properties, signals, methods, constructors, etc. with pure C++? The ability to dynamically and safely hook up objects based on their method signatures, even across library boundaries. The ability to have QtScript/Qml bindings for free. All this is, without writing code extra yourself.

I’m sorry, but I’m professionally working on large Qt projects every day and we heavily use features that the MOC provide to simplify our life and to require less code. And you know what, we even wish that the MOC did even more!

For the record, we switched AWAY from wxWidgets to embrace Qt.

Surik Sayadyan says:

I translated this post into Russian.

http://habrahabr.ru/blogs/qt_software/120127/

Stephen Chu says:

@Hendrik

Well. Then we need clang support in Qt ASAP.

charley says:

+1 to @Alex (comment #19)

Alex spaketh:==>

And how do you get object introspection? The ability to enumerate properties, signals, methods, constructors, etc. with pure C++? The ability to dynamically and safely hook up objects based on their method signatures, even across library boundaries. The ability to have QtScript/Qml bindings for free. All this is, without writing code extra yourself.

I’m sorry, but I’m professionally working on large Qt projects every day and we heavily use features that the MOC provide to simplify our life and to require less code. And you know what, we even wish that the MOC did even more!
<===

Timur Kristóf says:

Thank you for these wonderful news!

My favourite C++0x feature are the lambdas. I was hoping that you could fix Qt Creator’s current behaviour with lambda functions.
See http://bugreports.qt.nokia.com/browse/QTCREATORBUG-4439 for the details.
I’m not saying that you should make them fully supported, but it would be nice if you could stop them from messing up Qt Creator.

Cheers,
Timur

Danny says:

@Stephen Chu
“Well. Then we need clang support in Qt ASAP.”

No, we don’t. Go research what Clang is and why Apple is adopting it instead of making demands.

Serguei Boldyrev says:

@Olivier: have a look at QtClosure project, btw, is Morten is no longer working with concurrent? And what are those plans regarding Qt5.0?

OtengiM says:

Really Looks promising. Qt is a C++ API. I dont care about QML or Javascript and all that stuff that Nokia came with lately. I just want a solid GUI API as Qt from trolltechs was using C++.

thrGT says:

Nice to hear Qt is about to use more of the Standard C++, but still I’ve got one question, even though it might look a bit OT:

In C++, there’s STL and the Standard Library. It implements all kinds of containers, which are highly optimised by a bunch of smart people who had written the Library. Then, there’s Boost, some parts of which possibly will be included in the new C++ standard library, namely the shared pointer stuff and a few handy routines as well. Now Qt goes as far as reimplementing both, even the Standard containers! At the same time, GTK and GNOME use the standard C++ tech, and advertise that as one f the main advantages of their toolkit! And they *do* have a point there.

Why is this? Is the Standard not for all the devs out there? Or is this done for the sake of “compatibility”, “supporting old compilers” and “being crossplatform” (the latter, and the compatibility thing, is the main reason why the STL had been invented) to be able to *sell* Commercial Qt to those enterprises that operate in *weird* programming environments and platforms? If this is the reason, then I might go as far as saying that Qt (Trolltech/Nokia) sacrifices the progress of the science (which embracing *standard* C++ is) in favor of their commercial interest.

P.S. I wonder what Donald Ervin Knuth would say if he saw us all reimplement stuff because of our own laziness and commercial benefit… that’s definitely *not* what he and all the CS researchers had in mind when they had created programming and algorithms.

Olivier Goffart says:

@Stephen Chu: clang already works with Qt. It is even possible to compile Qt with clang: http://labs.qt.nokia.com/2010/10/29/compiling-qt-with-clang/

@Achilleas Margaritis and Jason: check out http://developer.qt.nokia.com/wiki/New_Signal_Slot_Syntax for the research on signals and slots

@thrGT: STL and Qt containers have different use cases. Qt containers are designed to assist the creation of a GUI. They are seen as simpler to use by some people. In particular, the implicitly sharing and the consistent API.

Jec says:

I’m glad you folks are still supporting C++. I came to Qt to get away from Java (man RTC languages are sooooo slow). I hope you guys always keep a C++ way of doing things. I know you’re proud of QML and QtQuick, but its easier for myself to know 1 language instead of 3.

Commenting closed.