C++11 in Qt

欧冠决赛结束了:所有有权有势的人都不希望马竞赢球,这样诞生了一个最水的欧洲冠军。

创造历史真不是一件容易的事儿。

言归正传,之前写了很多关于C++11的文章,因为C++11使得C++看上去像是一门全新的语言。

Qt可以说是对C++的类用到了极致,所以接下来跟大家分享的就是C++11在Qt中的使用。

为了能够使用C++11,需要在.pro文件中加入:

CONFIG += c++11

Slots中使用Lambda表达式

lambda表达式:c++11特性之Lambda表达式

slots:QT中的信号-槽比我们常用的callback到底牛在哪里?

connect(sender, &Sender::valueChanged, [=](const QString &newValue) {
 receiver->updateValue("senderValue", newValue);
   });

Unicode literal
在C++11中,可以使用u”MyString”来表示一个UTF-16。
这样在Qt中有相应的QStringLiteral。

QString s1 = "foo";        // Implementation character set string
QString s2 = R"(foo\bar)"; // Raw string, no need to escape backslashes
QString s3 = u8"foo";      // UTF-8 string
QString s4 = u8R"(foo)";   // UTF-8 raw string
QString s5 = QString::fromUtf16(reinterpret_cast<const ushort *>(u"foo"));    // UTF-16 string
QString s6 = QString::fromUtf16(reinterpret_cast<const ushort *>(uR"(foo)")); // UTF-16 raw string
QString s7 = QString::fromUcs4(reinterpret_cast<const uint *>(U"foo"));       // UTF-32 string
QString s8 = QString::fromUcs4(reinterpret_cast<const uint *>(UR"(foo)"));    // UTF-32 raw string

常量表达式:constexpr
constexpr变量

在一个复杂系统中,很难(几乎肯定不能)分辨一个初始值到底是不是常量表达式。当然可以定义一个const变量并把它的初始值设为我们认为的某个常量表达式,但在实际使用时,尽管要求如此却常常发现初始值并非常量表达式的情况。可以这么说,在此种情况下,对象的定义和使用根本就是两回事儿。

C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

constexpr int mf = 20;          // 20是常量表达式 
constexpr int limit = mf + 1;   // mf + 1是常量表达式 
constexpr int sz = size();      // 只有当size是一个constexpr函数时

z在Qt 5, 有Q_DECL_CONSTEXPR:

enum SomeEnum { Value1, Value2, Value3 };
Q_DECLARE_OPERATORS_FOR_FLAGS(QFlags<SomeEnum>)
// The previous line declares
// Q_DECL_CONSTEXPR QFlags<SomeValue> operator|(SomeValue,SomeValue) {...}

int someFunction(QFlags<SomeEnum> value) {
    switch (value) {
        case SomeEnum::Value1:
            return 1;
        case SomeEnum::Value2:
            return 2;
        case SomeEnum::Value1 | SomeEnum::Value3:
        // Only possible with C++11 and because QFlags operators are constexpr
        // Previously this line would call
        // QFlags<SomeValue> operator|(SomeValue,SomeValue)
        // that would have thrown an error because only compiler constants
        // are allowed as case satement

            return 3;
        default:
            return 0;
    }
}

static_assert
C++11 helps producing better error messages when something wrong can be detected at compile time using static_assert. In Qt5 we introduced the macros Q_STATIC_ASSERT, and Q_STATIC_ASSERT_X That will use static_assert if available, or some other template trick if not.

Override and final
C++11中增加了override和final关键字,之前也说过:
c++11特性之override和final关键字

qt中 Q_DECL_OVERRIDE和Q_DECL_FINAL

class MyModel : public QStringListModel {
    //...
protected:
     Qt::ItemFlags flags (const QModelIndex & index)  Q_DECL_OVERRIDE;
};

nullptr常量

    char *pc = nullptr;   // OK
    int  *pi = nullptr;   // OK
    bool  bp = nullptr;   // OK, bp will be set to false.
    int i    = nullptr;   // Compile error: can't convert a nullptr to int.

初始化列表Initializer Lists
之前:

    QStringList fruit;
    fruit << "apple" << "pear" << "peach" << "tomato";

现在:

QStringList fruit{"apple", "pear", "peach", "tomato"};

基于范围的for循环
使用qt中的foreach:

    QStringList options{"a", "b", "c", "d"};

    foreach(const QString &option, options) {
        std::cout << qPrintable(option) << std::endl;
    }

C++11:

    QStringList options{"a", "b", "c", "d"};

    for (const QString & option : options) {
        std::cout << qPrintable(option) << std::endl;
    }

总结
MSVC does not require any special flags and enables the C++11 features by default, but GCC or Clang require -std=c++0x.

By default, Qt5 itself will be compiled with the C++11 flags on compilers that need it.

If you use qmake, you can add that line to your .pro file (Qt5):

CONFIG += c++11
(In Qt4, it should be something like: gcc:CXXFLAGS += -std=c++0x)

And now you can enjoy all the nice features of C++11. (It is already worth doing it only for being able to use auto)

你可能感兴趣的:(qt)