7

Click here to load reader

C++14 for Qt programmers

Embed Size (px)

DESCRIPTION

Note for Qt Programmers about C++

Citation preview

  • woboq.com

    C++14 for Qt programmers

    C++14 is the name of the version of the standard to be released

    this year. While C++11 has brought many more feature that took

    time to be implemented by the compilers, C++14 is a much lighter

    change that is already implemented by compilers such as clang or

    gcc.

    Qt 5 already was adapted in many ways so you can make use of

    the new features of C++11. You can read about that in my previous

    article. C++11 in Qt5 . This article mention some of the changes in

    C++14 and the impact on Qt users.

    Generic lambda

    C++11 introduced lambda function, and Qt5 allow you to connect

    signals to them with the new connect syntax. C++14 simplify the

    use of lambda function as the arguments can be automatically

    deduced. You can use auto as parameter type instead of explicitly

    writing the type.

    connect(sender, &Sender::valueChanged, [=](const

    auto &newValue) {

    receiver->updateValue("senderValue",

    newValue);

    });

    Internally, lambda function is just a functor object with an

    operator(). With generic lamdba, that operator is now a

    templated function. I had to make a change which was included in

    Qt 5.1 already to support such functors.

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    1 of 7 30/07/2015 19:11

  • C++14 also adds the possibility to have expressions in the capture.

    connect(sender, &Sender::valueChanged,

    [reciever=getReciever()](const auto &newValue) {

    receiver->updateValue("senderValue",

    newValue);

    });

    Relaxed Constant expressions

    C++11 came with the new constexpr keyword. Qt 4.8 has added

    a new macro Q_DECL_CONSTEXPR that expands to constexpr

    when supported, and we have been using it for many function when

    possible in Qt 5.

    C++14 is relaxing the rules of what is allowed in a constexpr. C++11

    rules were only allowing a single return statement, and could only

    be applied on const functions. C++14 allow pretty much any code

    that can be evaluated at compile time.

    /* This function was not valid in C++11 because

    it is composed of several statements,

    * it has a loop, and a local variable. It is now

    allowed in C++14 */

    constexpr int myFunction(int v) {

    int x = 1;

    while (x < v*v)

    x*=2;

    return x;

    }

    Member functions declared as constexpr in C++11 were

    automatically considered as const. It is no longer the case as

    non-const function can also be constexpr.

    The result of this change is that constexpr member functions that

    were not explicitly marked as const will change const-ness in

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    2 of 7 30/07/2015 19:11

  • C++14, and this is a binary incompatible change. Fortunately in Qt,

    all Q_DECL_CONSTEXPR member functions were also explicitly

    declared as const to keep binary compatibility with non C++11

    code.

    So now we can start annotating non-const functions such as

    operator= of many classes. For this reason, Qt 5.5 will come with

    a new macro Q_DECL_RELAXED_CONSTEXPR which expands to

    constexpr when the compiler is in a C++14 mode. We will then

    be able to start annotating relevant functions with

    Q_DECL_RELAXED_CONSTEXPR

    Small features

    C++14 also comes with a lot of small convenience feature. That do

    not have direct impact on Qt, but can be used in your program if

    you enable C++14. We just made sure that tools like moc can

    handle them.

    Group Separators in Numbers

    If you are writing huge constant in your code, you can now now use

    ' as a group separator:

    int i = 123'456'789;

    Binary literal

    In C++ you can write your number in decimal, octal (starting your

    number with 0), hexadecimal (starting with 0x). You can now also

    write in binary by using the 0b prefix.

    int i = 0b0001'0000'0001;

    Automatic return type detection

    If you have an inline function, you can use auto as a return type,

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    3 of 7 30/07/2015 19:11

  • and you do no longer need to specify it. The compiler will deduce it

    for you

    // return type auto detected to be 'int'

    auto sum(int a, int b) { return a+b; }

    This is, however, not supported for slot or invokable method as moc

    would not be able to detect the return type

    Variable template

    You could have functions template or class template. Now you can

    also have variable template.

    template const T pi =

    3.141592653589793;

    /*...*/

    float f = pi;

    double d = pi;

    Uniform initialization of structures with non static data

    member initializers

    In C++11, you can use the uniform initialization to initialize a struct

    that has no constructor by initializing all the members. C++11 also

    added the possibility to have inline non static data member

    initiazers directly in the class declaration. But you could not use the

    two at the same time. In C++14, you can. This code works and do

    what you would expect:

    struct MyStruct {

    int x;

    QString str;

    bool flag = false;

    QByteArray str2 = "something";

    };

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    4 of 7 30/07/2015 19:11

  • // ...

    // did not compile in C++11 because MyStruct

    was not an "aggregate"

    MyStruct s = { 12, "1234", true };

    Q_ASSERT(s.str2 == "something");

    Reference Qualifiers

    This is not a C++14 feature, but a C++11 change. But we only

    started to make use of this late in the Qt5 cycle and I did not

    mention it in a previous blog post so I'll mention it here.

    Consider this code:

    QString lower =

    QString::fromUtf8(data).toLower();

    fromUtf8 returns a temporary. It would be nice if the toLower

    could re-use the memory allocated by the string and do the

    transformation in place. Well that's what the reference qualifiers for

    member functions are for.

    (code simplified from qstring.h:)

    class QString {

    public:

    /* ... */

    QString toLower() const &

    { /* ... returns a copy with lower case

    character ... */ }

    QString toLower() &&

    { /* ... do the conversion in-place ... */ }

    /* ... */

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    5 of 7 30/07/2015 19:11

  • };

    Notice the '&' and '&&' at the end of toLower. Those are

    references qualifier and let overload a function depending on the

    reference type of the 'this' pointer, just like the const qualifier let

    overload on the constness of this. When toLower is called on a

    temporary (a rvalue reference) the second overload (the one with

    &&) will be chosen and the transformation will be done in place.

    The functions that benefit from the optimisation in Qt 5.4 are:

    QString::toUpper, QString::toLower,

    QString::toCaseFolded, QString::toLatin1,

    QString::toLocal8Bit, QString::toUtf8,

    QByteArray::toUpper, QByteArray::toLower,

    QImage::convertToFormat, QImage::mirorred,

    QImage::rgbSwapped,

    QVersionNumber::normalized,

    QVersionNumber::segment

    Changes in the standard library.

    C++11 and C++14 have added a lot of feature to the standard

    library, competing with many of the features of QtCore. However, Qt

    makes little use of the standard library. In particular, we do not want

    to have the standard library as part of the ABI. This would allow to

    stay binary compatible even when the standard library is changed

    (example libstdc++ vs. libcpp). Also, Qt still supports older

    platforms that do not have the C++11 standard library. This really

    limits our uses.

    Yet, Qt5 deprecated its own algorithms library and is now

    recommending to use the algorithms from the STL (example,

    std::sort instead of qSort).

    Conclusion

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    6 of 7 30/07/2015 19:11

  • It may still take some time before you can use those features in

    your project. But I hope that, by now, you started using C++11

    features like many others projects did (Qt Creator, KDE, LLVM).

    MSVC will enables C++14 by default with their new compilers, but

    clang and gcc require a special compilation flag (currently

    -std=c++1y). With qmake, you can enable your project to build

    with C++14 since Qt 5.4 by using this option:

    CONFIG += c++14

    C++14 for Qt programmers about:reader?url=http://woboq.com/blog/cpp14-in-qt.html

    7 of 7 30/07/2015 19:11