[Development] qMoveToConst helper for rvalue references to movable Qt containers?

Elvis Stansvik elvstone at gmail.com
Sat Oct 27 21:37:06 CEST 2018


Den lör 27 okt. 2018 kl 21:07 skrev Elvis Stansvik <elvstone at gmail.com>:
>
> Den lör 27 okt. 2018 kl 19:48 skrev Lars Knoll <lars.knoll at qt.io>:
> >
> >
> >
> > On 27 Oct 2018, at 19:29, André Pönitz <apoenitz at t-online.de> wrote:
> >
> > On Sat, Oct 27, 2018 at 04:33:30PM +0100, Sérgio Martins wrote:
> >
> > On Sat, Oct 20, 2018 at 1:44 PM Elvis Stansvik <elvstone at gmail.com> wrote:
> >
> >
> > Hi all (first post),
> >
> >
> > Welcome :)
> >
> > In Qt 5.7+ there's qAsConst, an std::as_const implementation for those
> > who are not on C++17 yet, which is convenient for iterating over Qt
> > containers using range-based for loops without causing a detach.
> >
> > For good reasons there's no version of qAsConst that takes an rvalue
> > reference, so you can't do e.g. for (auto foo :
> > qAsConst(returnsQtContainer())  { ... }. Instead you must do const
> > auto stuff = returnsQtContainer(); for (auto foo : stuff) { ... }.
> >
> >
> > Should we instead just encourage people to make returnsQtContainer()
> > return a const container ?
> >
> >
> > This is actually a route we recently took in some cases in Qt Creator's
> > code base.
> >
> >
> > That might actually make sense. Calling a non const method on the returned temporary object is usually a mistake anyway. And the copy/move assignment to a variable will work with the const object.
>
> Hm, but was Marc not right when he said
>
>   "Making returned containers const inhibits move semantics, because
> const rvalues do not bind to the mutable rvalue references that move
> constructors and move assignment operators use."
>
> on his blog?
>
> Guess he should jump in here to defend himself :)

Another problem I found when trying to apply this to our code base is
that it seems you can't QtConcurrent::run a function returning const
T, because internally, ResultStoreBase::addResult looks like

    template <typename T>
    int addResult(int index, const T *result)
    {
        if (result == 0)
            return addResult(index, static_cast<void *>(nullptr));
        else
            return addResult(index, static_cast<void *>(new T(*result)));
    }

so you'll get an error like

/usr/include/x86_64-linux-gnu/qt5/QtCore/qresultstore.h:151: error:
static_cast from 'const QVector<double> *' to 'void *' is not allowed
            return addResult(index, static_cast<void *>(new T(*result)));
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Just a small downside in our case, but still.

Elvis

>
> Elvis
>
> >
> > Cheers,
> > Lars
> >
> > _______________________________________________
> > Development mailing list
> > Development at qt-project.org
> > http://lists.qt-project.org/mailman/listinfo/development



More information about the Development mailing list