欧冠决赛结束了:所有有权有势的人都不希望马竞赢球,这样诞生了一个最水的欧洲冠军。
创造历史真不是一件容易的事儿。
言归正传,之前写了很多关于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)