I must admit that I'm still on Qt5.
However, QList
and QSet
remind me strong to std::list
and std::set
.
For the latter, there was already another (and more flexible) way to achieve such things:
using construction with iterators. A short check in the Qt6 doc. convinced me, this should work in the Qt classes as well:
QSet::QSet(InputIterator first, InputIterator last)
Constructs a set with the contents in the iterator range [first, last).
The value type of InputIterator must be convertible to T.
Note: If the range [first, last) contains duplicate elements, the first one is retained.
This function was introduced in Qt 5.14.
where first
is set with
QList::iterator QList::begin()
Returns an STL-style iterator pointing to the first item in the list.
and last
with
QList::iterator QList::end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list.
How this should look like when put together:
QList<QString> aList;
// populate list
QSet<QString> aSet(aList.begin(), aList.end());
OP noted that the Qt-5 doc. already contained a hint concerning this:
QSet QList::toSet() const
Note: Since Qt 5.14, range constructors are available for Qt's generic container classes and should be used in place of this method.
OP also mentioned a convenience wrapper:
template <typename T>
QSet<T> QListToQSet(const QList<T>& qlist)
{
return QSet<T> (qlist.constBegin(), qlist.constEnd());
}
applied to the above sample:
QList<QString> aList;
// populate list
QSet<QString> aSet = QListToQSet(aList);
A more general conversion facility would probably be something like this:
template <typename T, template<typename> typename C>
QSet<T> toQSet(const C<T> &container)
{
return QSet<T>(container.begin(), container.end());
}
which would work even with matching std
containers as well:
std::vector<QString> aVec = { "Hello", "World", "Hello" };
QSet<QString> aSet = toSet(aVec);
QStringList
doesn't havetoSet
on it any more, unfortunately. – Duodiode