Как преобразовать QList в QSet в Qt 6

Я портирую свое приложение на Qt 6, и, читая документацию, я вижу, что классы сильно очищены, и QVector унифицированы, теперь это псевдоним QList<QString> и так далее.

Но теперь у меня возникла одна проблема.

В моем коде (это Qt 5) я конвертирую QStringListчтобы удалить дубликаты из списка. Я просмотрел новую документацию, но не нашел способа конвертировать в Qt 6.

Итак, как вы конвертируете QList к QSet? Или это невозможно и мне нужно будет написать вспомогательную функцию для удаления дубликатов?

2 ответа

Решение

Должен признать, что я все еще использую Qt5.

Тем не мение, QList и QSet напомнить мне сильно std::list и std::set. Для последнего уже существовал другой (и более гибкий) способ достижения таких вещей: использование конструкции с итераторами. Небольшая проверка в документации Qt6. убедил меня, что это должно работать и в классах Qt:

QSet ::QSet(сначала InputIterator, затем InputIterator)

Создает набор с содержимым в диапазоне итератора [первый, последний).

Тип значения InputIterator должен быть конвертируемым в T.

Примечание. Если диапазон [первый, последний) содержит повторяющиеся элементы, первый сохраняется.

Эта функция была введена в Qt 5.14.

куда first установлен с

QList::iterator QList::begin()

Возвращает итератор в стиле STL, указывающий на первый элемент в списке.

и last с

QList::iterator QList:: end ()

Возвращает итератор в стиле STL, указывающий на воображаемый элемент после последнего элемента в списке.

Как это должно выглядеть в совокупности:

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

ОП отметил, что Qt-5 doc. уже содержал намек по этому поводу:

QSet QList :: toSet () const

Примечание: Начиная с 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);

вы правы, посмотрите в коде или в документе, что 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();
}
Другие вопросы по тегам