Как преобразовать 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. уже содержал намек по этому поводу:
Примечание: Начиная с 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();
}