2

我正在将我的应用程序移植到 Qt 6 并且在阅读文档时,我看到类被清理了很多,QList并且QVector是统一的,QStringList现在是别名QList<QString>等等。

但是现在这给了我一个问题。

在我的代码(即 Qt 5)中,我正在转换QStringListQSet以消除列表中的重复项。我浏览了新文档,但我还没有看到在 Qt 6中转换QList为的方法。QSet

那么如何转换QListQSet? 或者这是不可能的,我需要编写一个辅助函数来删除重复项?

编辑:我正在使用 Qt 6.0.1。

4

2 回答 2

2

我必须承认我还在使用 Qt5。

然而,QListQSet提醒我坚强地std::liststd::set。对于后者,已经有另一种(并且更灵活)的方式来实现这些目标:使用带有迭代器的构造。Qt6 文档中的简短检查。说服我,这也应该适用于 Qt 类:

QSet::QSet(InputIterator first, InputIterator last)

使用迭代器范围 [first, last) 中的内容构造一个集合。

InputIterator 的值类型必须可转换为 T。

注意:如果范围 [first, last) 包含重复元素,则保留第一个元素。

这个函数是在 Qt 5.14 中引入的。

在哪里first设置

QList::迭代器 QList::begin()

返回指向列表中第一项的 STL 样式迭代器。

last

QList::迭代器 QList::end()

返回一个 STL 风格的迭代器,指向列表中最后一项之后的虚构项。

放在一起应该是什么样子:

QList<QString> aList;
// populate list
QSet<QString> aSet(aList.begin(), aList.end());

OP 注意到 Qt-5 文档。已经包含有关此的提示:

QSet QList::toSet() 常量

注意:从 Qt 5.14 开始,范围构造函数可用于 Qt 的通用容器类,并且应该用来代替此方法。

OP 还提到了一个方便的包装器:

template <typename T>
QSet<T> QListToQSet(const QList<T>& qlist)
{
  return QSet<T> (qlist.constBegin(), qlist.constEnd());
}

应用于上述样本:

QList<QString> aList;
// populate list
QSet<QString> aSet = QListToQSet(aList);

更通用的转换工具可能是这样的:

template <typename T, template<typename> typename C>
QSet<T> toQSet(const C<T> &container)
{
  return QSet<T>(container.begin(), container.end());
}

这甚至适用于匹配的std容器:

std::vector<QString> aVec = { "Hello", "World", "Hello" };
QSet<QString> aSet = toSet(aVec);
于 2021-02-10T09:49:56.940 回答
0

你是对的,在代码文档中看到 QStringList 是 QList 的孩子

class QStringList : public QList<QString>
{

所以你可以调用 QSet toSet() const; 直接因为方法是公开的。

有了这个,您可以直接将QStringlist的内容解压缩到qset

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QString str = "one,two,three,four,one";
    QStringList strlt = str.split(QChar(','));

    const QSet<QString> strVe = strlt.toSet();
    qDebug() << strVe;

    return a.exec();
}
于 2021-02-09T16:56:49.017 回答