Question

What is the output of the following code:

QString separator = "/";
auto date = "14" + separator + "7" + separator + "2013";
separator = " ";
auto datetime = date + separator + "17:32";
qDebug() << datetime;
Scroll down…
Expected output: "14/7/2013 17:32"
Actual output:   "14 7 2013 17:32"

What happened?

In his great talk, Volker mentioned the optimizations of QString concatenation via the auto, expression templates and QStringBuilder that allow to do a single memory allocation for all the concatenations in the example above.

I just wanted to repeat a warning I gave to the audience - for the people who were not present.

In this case, auto allows the lazy evaluation of the result (which provides the actual optimization). “Lazy” means that the separator value is only taken at the point of the actual evaluation which happens only when the QStringBuilder is being converted to a string in order to be able to output it via qDebug. At that point, the value of separator is ” “, and the old value”/” has been forgotten.

The lazy evaluation is usually a trait of pure functional languages (Haskell) where there is no mutable state. When you have the mutable state, you need to really pay attention whether you are using an expression template-based API.

When?

This mechanism is only used when either QT_USE_FAST_OPERATOR_PLUS or QT_USE_QSTRINGBUILDER are defined. And those are, by default, in KDE Frameworks 5.