我尝试对代码进行一些优化,发现我对QRegExp
的使用不涉及它的任何非const方法:
我拥有的代码:
QString parse(const QString &data) {
static const QRegExp DATA_REGEXP(QStringLiteral("^(\\w{4}) (\\w{4}) SN=(\\w*)"));
if (DATA_REGEXP.indexIn(data) != -1) {
const QString vendorId = DATA_REGEXP.cap(1);
const QString modelId = DATA_REGEXP.cap(2);
const QString serial = DATA_REGEXP.cap(3);
// ...
}
// ...
}
我想知道这怎么可能(具有const
方法实际上是在改变对象),检查了the code并发现,即使方法被声明为const
,它们仍然在内部使用可变对象(不要与mutable
关键字混淆)私有对象(Qt使用PIMPL习惯用语)。因此,现在我想知道在此indexIn
对象上调用cap
和static const QRegExp
是否安全?这些方法似乎并不是可重用的,因为它们在多个线程中的使用将导致共享内存的更改,所以我想我必须使用同步原语,对吗?
答案 0 :(得分:2)
QRegExp的所有功能都是 reentant ,但不是threadsafe。因此,如果仅在单个线程中运行,则此代码会很好。
如果要从多个线程调用此函数,则有两个选择:
QRegExp
实例static
,所以不同的线程具有不同的实例。thread_local
(如StoryTeller所指出的那样)我会避免第一种选择,因为暂停线程很少是一个好主意。
答案 1 :(得分:2)
在这种特殊情况下,doc fo indexIn()指出:
尽管是const,但此函数设置matchLength(),capturedTexts()和pos()。
很明显,这意味着indexIn()
不应为常量。
除了这种特殊情况外,Qt类的确将const传播到其私有指针。
对于您而言,我建议您使用QRegularExpression
,因为进行匹配不会修改正则表达式的状态,而是返回一个QRegularExpressionMatch
对象。
再次引用Qt documentation:
Qt 5中引入的QRegularExpression类是一个很大的改进 在QRegExp上,就提供的API而言,支持的模式语法和 执行速度。最大的区别是QRegularExpression 只包含一个正则表达式,匹配时不会对其进行修改 被要求。而是返回QRegularExpressionMatch对象, 为了检查比赛结果并提取捕获的 子字符串。全局匹配和 QRegularExpressionMatchIterator。
其他区别如下。